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 static const float id_mat
[16] = {
62 static void draw_primitive_strided_7(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 d1
, d2
;
277 fill_opengl_caps(&d1
);
280 TRACE(" enumerating OpenGL D3DDevice interface using reference IID (IID %s).\n", debugstr_guid(&IID_IDirect3DRefDevice
));
281 ret_value
= cb((LPIID
) &IID_IDirect3DRefDevice
, "WINE Reference Direct3DX using OpenGL", "direct3d", &d1
, &d2
, context
);
282 if (ret_value
!= D3DENUMRET_OK
)
285 TRACE(" enumerating OpenGL D3DDevice interface (IID %s).\n", debugstr_guid(&IID_D3DDEVICE_OpenGL
));
286 ret_value
= cb((LPIID
) &IID_D3DDEVICE_OpenGL
, "WINE Direct3DX using OpenGL", "direct3d", &d1
, &d2
, context
);
287 if (ret_value
!= D3DENUMRET_OK
)
290 return D3DENUMRET_OK
;
293 HRESULT
d3ddevice_enumerate7(LPD3DENUMDEVICESCALLBACK7 cb
, LPVOID context
)
295 D3DDEVICEDESC7 ddesc
;
297 fill_opengl_caps_7(&ddesc
);
299 TRACE(" enumerating OpenGL D3DDevice7 interface.\n");
301 return cb("WINE Direct3D7 using OpenGL", "Wine D3D7 device", &ddesc
, context
);
305 GL_IDirect3DDeviceImpl_7_3T_2T_1T_Release(LPDIRECT3DDEVICE7 iface
)
307 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
308 IDirect3DDeviceGLImpl
*glThis
= (IDirect3DDeviceGLImpl
*) This
;
310 TRACE("(%p/%p)->() decrementing from %lu.\n", This
, iface
, This
->ref
);
311 if (!--(This
->ref
)) {
312 /* Release texture associated with the device */
313 if (This
->current_texture
[0] != NULL
)
314 IDirect3DTexture2_Release(ICOM_INTERFACE(This
->current_texture
[0], IDirect3DTexture2
));
316 /* And warn the D3D object that this device is no longer active... */
317 This
->d3d
->removed_device(This
->d3d
, This
);
319 HeapFree(GetProcessHeap(), 0, This
->world_mat
);
320 HeapFree(GetProcessHeap(), 0, This
->view_mat
);
321 HeapFree(GetProcessHeap(), 0, This
->proj_mat
);
324 glXDestroyContext(glThis
->display
, glThis
->gl_context
);
327 HeapFree(GetProcessHeap(), 0, This
);
334 GL_IDirect3DDeviceImpl_3_2T_1T_GetCaps(LPDIRECT3DDEVICE3 iface
,
335 LPD3DDEVICEDESC lpD3DHWDevDesc
,
336 LPD3DDEVICEDESC lpD3DHELDevDesc
)
338 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
342 TRACE("(%p/%p)->(%p,%p)\n", This
, iface
, lpD3DHWDevDesc
, lpD3DHELDevDesc
);
344 fill_opengl_caps(&desc
);
345 dwSize
= lpD3DHWDevDesc
->dwSize
;
346 memset(lpD3DHWDevDesc
, 0, dwSize
);
347 memcpy(lpD3DHWDevDesc
, &desc
, (dwSize
<= desc
.dwSize
? dwSize
: desc
.dwSize
));
349 dwSize
= lpD3DHELDevDesc
->dwSize
;
350 memset(lpD3DHELDevDesc
, 0, dwSize
);
351 memcpy(lpD3DHELDevDesc
, &desc
, (dwSize
<= desc
.dwSize
? dwSize
: desc
.dwSize
));
353 TRACE(" returning caps : (no dump function yet)\n");
358 static HRESULT
enum_texture_format_OpenGL(LPD3DENUMTEXTUREFORMATSCALLBACK cb_1
,
359 LPD3DENUMPIXELFORMATSCALLBACK cb_2
,
363 LPDDPIXELFORMAT pformat
;
365 /* Do the texture enumeration */
366 sdesc
.dwSize
= sizeof(DDSURFACEDESC
);
367 sdesc
.dwFlags
= DDSD_PIXELFORMAT
| DDSD_CAPS
;
368 sdesc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
369 pformat
= &(sdesc
.ddpfPixelFormat
);
370 pformat
->dwSize
= sizeof(DDPIXELFORMAT
);
371 pformat
->dwFourCC
= 0;
373 TRACE("Enumerating GL_RGBA unpacked (32)\n");
374 pformat
->dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
375 pformat
->u1
.dwRGBBitCount
= 32;
376 pformat
->u2
.dwRBitMask
= 0xFF000000;
377 pformat
->u3
.dwGBitMask
= 0x00FF0000;
378 pformat
->u4
.dwBBitMask
= 0x0000FF00;
379 pformat
->u5
.dwRGBAlphaBitMask
= 0x000000FF;
380 if (cb_1
) if (cb_1(&sdesc
, context
) == 0) return DD_OK
;
381 if (cb_2
) if (cb_2(pformat
, context
) == 0) return DD_OK
;
383 TRACE("Enumerating GL_RGB unpacked (24)\n");
384 pformat
->dwFlags
= DDPF_RGB
;
385 pformat
->u1
.dwRGBBitCount
= 24;
386 pformat
->u2
.dwRBitMask
= 0x00FF0000;
387 pformat
->u3
.dwGBitMask
= 0x0000FF00;
388 pformat
->u4
.dwBBitMask
= 0x000000FF;
389 pformat
->u5
.dwRGBAlphaBitMask
= 0x00000000;
390 if (cb_1
) if (cb_1(&sdesc
, context
) == 0) return DD_OK
;
391 if (cb_2
) if (cb_2(pformat
, context
) == 0) return DD_OK
;
393 TRACE("Enumerating GL_RGB packed GL_UNSIGNED_SHORT_5_6_5 (16)\n");
394 pformat
->dwFlags
= DDPF_RGB
;
395 pformat
->u1
.dwRGBBitCount
= 16;
396 pformat
->u2
.dwRBitMask
= 0x0000F800;
397 pformat
->u3
.dwGBitMask
= 0x000007E0;
398 pformat
->u4
.dwBBitMask
= 0x0000001F;
399 pformat
->u5
.dwRGBAlphaBitMask
= 0x00000000;
400 if (cb_1
) if (cb_1(&sdesc
, context
) == 0) return DD_OK
;
401 if (cb_2
) if (cb_2(pformat
, context
) == 0) return DD_OK
;
403 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_5_5_5_1 (16)\n");
404 pformat
->dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
405 pformat
->u1
.dwRGBBitCount
= 16;
406 pformat
->u2
.dwRBitMask
= 0x0000F800;
407 pformat
->u3
.dwGBitMask
= 0x000007C0;
408 pformat
->u4
.dwBBitMask
= 0x0000003E;
409 pformat
->u5
.dwRGBAlphaBitMask
= 0x00000001;
410 if (cb_1
) if (cb_1(&sdesc
, context
) == 0) return DD_OK
;
411 if (cb_2
) if (cb_2(pformat
, context
) == 0) return DD_OK
;
413 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_4_4_4_4 (16)\n");
414 pformat
->dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
415 pformat
->u1
.dwRGBBitCount
= 16;
416 pformat
->u2
.dwRBitMask
= 0x0000F000;
417 pformat
->u3
.dwGBitMask
= 0x00000F00;
418 pformat
->u4
.dwBBitMask
= 0x000000F0;
419 pformat
->u5
.dwRGBAlphaBitMask
= 0x0000000F;
420 if (cb_1
) if (cb_1(&sdesc
, context
) == 0) return DD_OK
;
421 if (cb_2
) if (cb_2(pformat
, context
) == 0) return DD_OK
;
423 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_1_5_5_5 (16)\n");
424 pformat
->dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
425 pformat
->u1
.dwRGBBitCount
= 16;
426 pformat
->u2
.dwRBitMask
= 0x00007C00;
427 pformat
->u3
.dwGBitMask
= 0x000003E0;
428 pformat
->u4
.dwBBitMask
= 0x0000001F;
429 pformat
->u5
.dwRGBAlphaBitMask
= 0x00008000;
430 if (cb_1
) if (cb_1(&sdesc
, context
) == 0) return DD_OK
;
431 if (cb_2
) if (cb_2(pformat
, context
) == 0) return DD_OK
;
433 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_4_4_4_4 (ARGB) (16)\n");
434 pformat
->dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
435 pformat
->u1
.dwRGBBitCount
= 16;
436 pformat
->u2
.dwRBitMask
= 0x00000F00;
437 pformat
->u3
.dwGBitMask
= 0x000000F0;
438 pformat
->u4
.dwBBitMask
= 0x0000000F;
439 pformat
->u5
.dwRGBAlphaBitMask
= 0x0000F000;
440 if (cb_1
) if (cb_1(&sdesc
, context
) == 0) return DD_OK
;
441 if (cb_2
) if (cb_2(pformat
, context
) == 0) return DD_OK
;
443 TRACE("Enumerating GL_RGB packed GL_UNSIGNED_BYTE_3_3_2 (8)\n");
444 pformat
->dwFlags
= DDPF_RGB
;
445 pformat
->u1
.dwRGBBitCount
= 8;
446 pformat
->u2
.dwRBitMask
= 0x000000E0;
447 pformat
->u3
.dwGBitMask
= 0x0000001C;
448 pformat
->u4
.dwBBitMask
= 0x00000003;
449 pformat
->u5
.dwRGBAlphaBitMask
= 0x00000000;
450 if (cb_1
) if (cb_1(&sdesc
, context
) == 0) return DD_OK
;
451 if (cb_2
) if (cb_2(pformat
, context
) == 0) return DD_OK
;
453 TRACE("Enumerating GL_ARGB (no direct OpenGL equivalent - conversion needed)\n");
454 pformat
->dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
455 pformat
->u1
.dwRGBBitCount
= 16;
456 pformat
->u2
.dwRBitMask
= 0x00007C00;
457 pformat
->u3
.dwGBitMask
= 0x000003E0;
458 pformat
->u4
.dwBBitMask
= 0x0000001F;
459 pformat
->u5
.dwRGBAlphaBitMask
= 0x00008000;
460 if (cb_1
) if (cb_1(&sdesc
, context
) == 0) return DD_OK
;
461 if (cb_2
) if (cb_2(pformat
, context
) == 0) return DD_OK
;
463 TRACE("Enumerating Paletted (8)\n");
464 pformat
->dwFlags
= DDPF_PALETTEINDEXED8
;
465 pformat
->u1
.dwRGBBitCount
= 8;
466 pformat
->u2
.dwRBitMask
= 0x00000000;
467 pformat
->u3
.dwGBitMask
= 0x00000000;
468 pformat
->u4
.dwBBitMask
= 0x00000000;
469 pformat
->u5
.dwRGBAlphaBitMask
= 0x00000000;
470 if (cb_1
) if (cb_1(&sdesc
, context
) == 0) return DD_OK
;
471 if (cb_2
) if (cb_2(pformat
, context
) == 0) return DD_OK
;
473 TRACE("End of enumeration\n");
479 d3ddevice_find(IDirect3DImpl
*d3d
,
480 LPD3DFINDDEVICESEARCH lpD3DDFS
,
481 LPD3DFINDDEVICERESULT lplpD3DDevice
)
485 if ((lpD3DDFS
->dwFlags
& D3DFDS_COLORMODEL
) &&
486 (lpD3DDFS
->dcmColorModel
!= D3DCOLOR_RGB
)) {
487 TRACE(" trying to request a non-RGB D3D color model. Not supported.\n");
488 return DDERR_INVALIDPARAMS
; /* No real idea what to return here :-) */
490 if (lpD3DDFS
->dwFlags
& D3DFDS_GUID
) {
491 TRACE(" trying to match guid %s.\n", debugstr_guid(&(lpD3DDFS
->guid
)));
492 if ((IsEqualGUID(&IID_D3DDEVICE_OpenGL
, &(lpD3DDFS
->guid
)) == 0) &&
493 (IsEqualGUID(&IID_IDirect3DHALDevice
, &(lpD3DDFS
->guid
)) == 0) &&
494 (IsEqualGUID(&IID_IDirect3DRefDevice
, &(lpD3DDFS
->guid
)) == 0)) {
495 TRACE(" no match for this GUID.\n");
496 return DDERR_INVALIDPARAMS
;
500 /* Now return our own GUID */
501 lplpD3DDevice
->guid
= IID_D3DDEVICE_OpenGL
;
502 fill_opengl_caps(&desc
);
503 lplpD3DDevice
->ddHwDesc
= desc
;
504 lplpD3DDevice
->ddSwDesc
= desc
;
506 TRACE(" returning Wine's OpenGL device with (undumped) capabilities\n");
512 GL_IDirect3DDeviceImpl_2_1T_EnumTextureFormats(LPDIRECT3DDEVICE2 iface
,
513 LPD3DENUMTEXTUREFORMATSCALLBACK lpD3DEnumTextureProc
,
516 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice2
, iface
);
517 TRACE("(%p/%p)->(%p,%p)\n", This
, iface
, lpD3DEnumTextureProc
, lpArg
);
518 return enum_texture_format_OpenGL(lpD3DEnumTextureProc
, NULL
, lpArg
);
522 GL_IDirect3DDeviceImpl_7_3T_EnumTextureFormats(LPDIRECT3DDEVICE7 iface
,
523 LPD3DENUMPIXELFORMATSCALLBACK lpD3DEnumPixelProc
,
526 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
527 TRACE("(%p/%p)->(%p,%p)\n", This
, iface
, lpD3DEnumPixelProc
, lpArg
);
528 return enum_texture_format_OpenGL(NULL
, lpD3DEnumPixelProc
, lpArg
);
532 GL_IDirect3DDeviceImpl_7_3T_2T_SetRenderState(LPDIRECT3DDEVICE7 iface
,
533 D3DRENDERSTATETYPE dwRenderStateType
,
536 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
537 IDirect3DDeviceGLImpl
*glThis
= (IDirect3DDeviceGLImpl
*) This
;
538 TRACE("(%p/%p)->(%08x,%08lx)\n", This
, iface
, dwRenderStateType
, dwRenderState
);
540 /* Call the render state functions */
541 set_render_state(dwRenderStateType
, dwRenderState
, &(glThis
->render_state
));
547 GL_IDirect3DDeviceImpl_3_2T_SetLightState(LPDIRECT3DDEVICE3 iface
,
548 D3DLIGHTSTATETYPE dwLightStateType
,
551 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
552 IDirect3DDeviceGLImpl
*glThis
= (IDirect3DDeviceGLImpl
*) This
;
554 TRACE("(%p/%p)->(%08x,%08lx)\n", This
, iface
, dwLightStateType
, dwLightState
);
556 switch (dwLightStateType
) {
557 case D3DLIGHTSTATE_MATERIAL
: { /* 1 */
558 IDirect3DMaterialImpl
*mat
= (IDirect3DMaterialImpl
*) dwLightState
;
565 ERR(" D3DLIGHTSTATE_MATERIAL called with NULL material !!!\n");
569 case D3DLIGHTSTATE_AMBIENT
: /* 2 */
570 /* Call the render_state function... */
571 set_render_state(D3DRENDERSTATE_AMBIENT
, dwLightState
, &(glThis
->render_state
));
574 #define UNSUP(x) case D3DLIGHTSTATE_##x: FIXME("unsupported D3DLIGHTSTATE_" #x "!\n");break;
584 TRACE("Unexpected Light State Type\n");
585 return DDERR_INVALIDPARAMS
;
592 GL_IDirect3DDeviceImpl_7_3T_2T_SetTransform(LPDIRECT3DDEVICE7 iface
,
593 D3DTRANSFORMSTATETYPE dtstTransformStateType
,
594 LPD3DMATRIX lpD3DMatrix
)
596 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
597 IDirect3DDeviceGLImpl
*glThis
= (IDirect3DDeviceGLImpl
*) This
;
599 TRACE("(%p/%p)->(%08x,%p)\n", This
, iface
, dtstTransformStateType
, lpD3DMatrix
);
603 /* Using a trial and failure approach, I found that the order of
604 Direct3D transformations that works best is :
606 ScreenCoord = ProjectionMat * ViewMat * WorldMat * ObjectCoord
608 As OpenGL uses only two matrices, I combined PROJECTION and VIEW into
609 OpenGL's GL_PROJECTION matrix and the WORLD into GL_MODELVIEW.
611 If anyone has a good explanation of the three different matrices in
612 the SDK online documentation, feel free to point it to me. For example,
613 which matrices transform lights ? In OpenGL only the PROJECTION matrix
614 transform the lights, not the MODELVIEW. Using the matrix names, I
615 supposed that PROJECTION and VIEW (all 'camera' related names) do
616 transform lights, but WORLD do not. It may be wrong though... */
618 /* After reading through both OpenGL and Direct3D documentations, I
619 thought that D3D matrices were written in 'line major mode' transposed
620 from OpenGL's 'column major mode'. But I found out that a simple memcpy
621 works fine to transfer one matrix format to the other (it did not work
622 when transposing)....
625 1) are the documentations wrong
626 2) does the matrix work even if they are not read correctly
627 3) is Mesa's implementation of OpenGL not compliant regarding Matrix
628 loading using glLoadMatrix ?
630 Anyway, I always use 'conv_mat' to transfer the matrices from one format
631 to the other so that if I ever find out that I need to transpose them, I
632 will able to do it quickly, only by changing the macro conv_mat. */
634 switch (dtstTransformStateType
) {
635 case D3DTRANSFORMSTATE_WORLD
: {
636 TRACE(" D3DTRANSFORMSTATE_WORLD :\n");
637 conv_mat(lpD3DMatrix
, This
->world_mat
);
638 if (glThis
->last_vertices_transformed
== FALSE
) {
639 glMatrixMode(GL_MODELVIEW
);
640 glLoadMatrixf((float *) This
->view_mat
);
641 glMultMatrixf((float *) This
->world_mat
);
645 case D3DTRANSFORMSTATE_VIEW
: {
646 TRACE(" D3DTRANSFORMSTATE_VIEW :\n");
647 conv_mat(lpD3DMatrix
, This
->view_mat
);
648 if (glThis
->last_vertices_transformed
== FALSE
) {
649 glMatrixMode(GL_MODELVIEW
);
650 glLoadMatrixf((float *) This
->view_mat
);
651 glMultMatrixf((float *) This
->world_mat
);
655 case D3DTRANSFORMSTATE_PROJECTION
: {
656 TRACE(" D3DTRANSFORMSTATE_PROJECTION :\n");
657 conv_mat(lpD3DMatrix
, This
->proj_mat
);
658 if (glThis
->last_vertices_transformed
== FALSE
) {
659 glMatrixMode(GL_PROJECTION
);
660 glLoadMatrixf((float *) This
->proj_mat
);
665 ERR("Unknown transform type %08x !!!\n", dtstTransformStateType
);
673 static void draw_primitive_start_GL(D3DPRIMITIVETYPE d3dpt
)
676 case D3DPT_POINTLIST
:
677 TRACE("Start POINTS\n");
682 TRACE("Start LINES\n");
686 case D3DPT_LINESTRIP
:
687 TRACE("Start LINE_STRIP\n");
688 glBegin(GL_LINE_STRIP
);
691 case D3DPT_TRIANGLELIST
:
692 TRACE("Start TRIANGLES\n");
693 glBegin(GL_TRIANGLES
);
696 case D3DPT_TRIANGLESTRIP
:
697 TRACE("Start TRIANGLE_STRIP\n");
698 glBegin(GL_TRIANGLE_STRIP
);
701 case D3DPT_TRIANGLEFAN
:
702 TRACE("Start TRIANGLE_FAN\n");
703 glBegin(GL_TRIANGLE_FAN
);
707 TRACE("Unhandled primitive\n");
712 static void draw_primitive_handle_GL_state(IDirect3DDeviceImpl
*This
,
713 BOOLEAN vertex_transformed
,
714 BOOLEAN vertex_lit
) {
715 IDirect3DDeviceGLImpl
* glThis
= (IDirect3DDeviceGLImpl
*) This
;
717 /* Puts GL in the correct lighting / transformation mode */
718 if ((vertex_transformed
== FALSE
) &&
719 (glThis
->last_vertices_transformed
== TRUE
)) {
720 /* Need to put the correct transformation again if we go from Transformed
721 vertices to non-transformed ones.
723 glMatrixMode(GL_MODELVIEW
);
724 glLoadMatrixf((float *) This
->view_mat
);
725 glMultMatrixf((float *) This
->world_mat
);
726 glMatrixMode(GL_PROJECTION
);
727 glLoadMatrixf((float *) This
->proj_mat
);
729 if (glThis
->render_state
.fog_on
== TRUE
) glEnable(GL_FOG
);
730 } else if ((vertex_transformed
== TRUE
) &&
731 (glThis
->last_vertices_transformed
== FALSE
)) {
732 GLfloat height
, width
;
733 GLfloat trans_mat
[16];
735 width
= glThis
->parent
.surface
->surface_desc
.dwWidth
;
736 height
= glThis
->parent
.surface
->surface_desc
.dwHeight
;
738 /* The X axis is straighforward.. For the Y axis, we need to convert 'D3D' screen coordinates
739 to OpenGL screen coordinates (ie the upper left corner is not the same).
740 For Z, the mystery is what should it be mapped to ? Ie should the resulting range be between
741 -1.0 and 1.0 (as the X and Y coordinates) or between 0.0 and 1.0 ? */
742 trans_mat
[ 0] = 2.0 / width
; trans_mat
[ 4] = 0.0; trans_mat
[ 8] = 0.0; trans_mat
[12] = -1.0;
743 trans_mat
[ 1] = 0.0; trans_mat
[ 5] = -2.0 / height
; trans_mat
[ 9] = 0.0; trans_mat
[13] = 1.0;
744 trans_mat
[ 2] = 0.0; trans_mat
[ 6] = 0.0; trans_mat
[10] = 1.0; trans_mat
[14] = -1.0;
745 trans_mat
[ 3] = 0.0; trans_mat
[ 7] = 0.0; trans_mat
[11] = 0.0; trans_mat
[15] = 1.0;
747 glMatrixMode(GL_MODELVIEW
);
749 glMatrixMode(GL_PROJECTION
);
750 glLoadMatrixf(trans_mat
);
752 /* Remove also fogging... */
756 /* Handle the 'no-normal' case */
757 if (vertex_lit
== FALSE
)
758 glDisable(GL_LIGHTING
);
759 else if (glThis
->render_state
.lighting_enable
== TRUE
)
760 glEnable(GL_LIGHTING
);
762 /* Handle the code for pre-vertex material properties */
763 if (vertex_transformed
== FALSE
) {
764 if (glThis
->render_state
.lighting_enable
== TRUE
) {
765 if ((glThis
->render_state
.color_diffuse
!= D3DMCS_MATERIAL
) ||
766 (glThis
->render_state
.color_specular
!= D3DMCS_MATERIAL
) ||
767 (glThis
->render_state
.color_ambient
!= D3DMCS_MATERIAL
) ||
768 (glThis
->render_state
.color_emissive
!= D3DMCS_MATERIAL
)) {
769 glEnable(GL_COLOR_MATERIAL
);
774 /* And save the current state */
775 glThis
->last_vertices_transformed
= vertex_transformed
;
779 inline static void draw_primitive(IDirect3DDeviceImpl
*This
, DWORD maxvert
, WORD
*index
,
780 D3DVERTEXTYPE d3dvt
, D3DPRIMITIVETYPE d3dpt
, void *lpvertex
)
782 D3DDRAWPRIMITIVESTRIDEDDATA strided
;
786 strided
.position
.lpvData
= &((D3DVERTEX
*) lpvertex
)->u1
.x
;
787 strided
.position
.dwStride
= sizeof(D3DVERTEX
);
788 strided
.normal
.lpvData
= &((D3DVERTEX
*) lpvertex
)->u4
.nx
;
789 strided
.normal
.dwStride
= sizeof(D3DVERTEX
);
790 strided
.textureCoords
[0].lpvData
= &((D3DVERTEX
*) lpvertex
)->u7
.tu
;
791 strided
.textureCoords
[0].dwStride
= sizeof(D3DVERTEX
);
792 draw_primitive_strided_7(This
, d3dpt
, D3DFVF_VERTEX
, &strided
, 0, 0 /* Unused */, index
, maxvert
, 0 /* Unused */);
795 case D3DVT_LVERTEX
: {
796 strided
.position
.lpvData
= &((D3DLVERTEX
*) lpvertex
)->u1
.x
;
797 strided
.position
.dwStride
= sizeof(D3DLVERTEX
);
798 strided
.diffuse
.lpvData
= &((D3DLVERTEX
*) lpvertex
)->u4
.color
;
799 strided
.diffuse
.dwStride
= sizeof(D3DLVERTEX
);
800 strided
.specular
.lpvData
= &((D3DLVERTEX
*) lpvertex
)->u5
.specular
;
801 strided
.specular
.dwStride
= sizeof(D3DLVERTEX
);
802 strided
.textureCoords
[0].lpvData
= &((D3DLVERTEX
*) lpvertex
)->u6
.tu
;
803 strided
.textureCoords
[0].dwStride
= sizeof(D3DLVERTEX
);
804 draw_primitive_strided_7(This
, d3dpt
, D3DFVF_LVERTEX
, &strided
, 0, 0 /* Unused */, index
, maxvert
, 0 /* Unused */);
807 case D3DVT_TLVERTEX
: {
808 strided
.position
.lpvData
= &((D3DTLVERTEX
*) lpvertex
)->u1
.sx
;
809 strided
.position
.dwStride
= sizeof(D3DTLVERTEX
);
810 strided
.diffuse
.lpvData
= &((D3DTLVERTEX
*) lpvertex
)->u5
.color
;
811 strided
.diffuse
.dwStride
= sizeof(D3DTLVERTEX
);
812 strided
.specular
.lpvData
= &((D3DTLVERTEX
*) lpvertex
)->u6
.specular
;
813 strided
.specular
.dwStride
= sizeof(D3DTLVERTEX
);
814 strided
.textureCoords
[0].lpvData
= &((D3DTLVERTEX
*) lpvertex
)->u7
.tu
;
815 strided
.textureCoords
[0].dwStride
= sizeof(D3DTLVERTEX
);
816 draw_primitive_strided_7(This
, d3dpt
, D3DFVF_TLVERTEX
, &strided
, 0, 0 /* Unused */, index
, maxvert
, 0 /* Unused */);
820 FIXME("Unhandled vertex type\n");
826 GL_IDirect3DDeviceImpl_2_DrawPrimitive(LPDIRECT3DDEVICE2 iface
,
827 D3DPRIMITIVETYPE d3dptPrimitiveType
,
828 D3DVERTEXTYPE d3dvtVertexType
,
833 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice2
, iface
);
834 TRACE("(%p/%p)->(%08x,%08x,%p,%08lx,%08lx)\n", This
, iface
, d3dptPrimitiveType
, d3dvtVertexType
, lpvVertices
, dwVertexCount
, dwFlags
);
837 draw_primitive(This
, dwVertexCount
, NULL
, d3dvtVertexType
, d3dptPrimitiveType
, lpvVertices
);
844 GL_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(LPDIRECT3DDEVICE2 iface
,
845 D3DPRIMITIVETYPE d3dptPrimitiveType
,
846 D3DVERTEXTYPE d3dvtVertexType
,
853 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice2
, iface
);
854 TRACE("(%p/%p)->(%08x,%08x,%p,%08lx,%p,%08lx,%08lx)\n", This
, iface
, d3dptPrimitiveType
, d3dvtVertexType
, lpvVertices
, dwVertexCount
, dwIndices
, dwIndexCount
, dwFlags
);
857 draw_primitive(This
, dwIndexCount
, dwIndices
, d3dvtVertexType
, d3dptPrimitiveType
, lpvVertices
);
864 GL_IDirect3DDeviceImpl_1_CreateExecuteBuffer(LPDIRECT3DDEVICE iface
,
865 LPD3DEXECUTEBUFFERDESC lpDesc
,
866 LPDIRECT3DEXECUTEBUFFER
* lplpDirect3DExecuteBuffer
,
869 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice
, iface
);
870 IDirect3DExecuteBufferImpl
*ret
;
873 TRACE("(%p/%p)->(%p,%p,%p)\n", This
, iface
, lpDesc
, lplpDirect3DExecuteBuffer
, pUnkOuter
);
875 ret_value
= d3dexecutebuffer_create(&ret
, This
->d3d
, This
, lpDesc
);
876 *lplpDirect3DExecuteBuffer
= ICOM_INTERFACE(ret
, IDirect3DExecuteBuffer
);
878 TRACE(" returning %p.\n", *lplpDirect3DExecuteBuffer
);
883 DWORD
get_flexible_vertex_size(DWORD d3dvtVertexType
, DWORD
*elements
)
888 if (d3dvtVertexType
& D3DFVF_NORMAL
) { size
+= 3 * sizeof(D3DVALUE
); elts
+= 1; }
889 if (d3dvtVertexType
& D3DFVF_DIFFUSE
) { size
+= sizeof(DWORD
); elts
+= 1; }
890 if (d3dvtVertexType
& D3DFVF_SPECULAR
) { size
+= sizeof(DWORD
); elts
+= 1; }
891 switch (d3dvtVertexType
& D3DFVF_POSITION_MASK
) {
892 case D3DFVF_XYZ
: size
+= 3 * sizeof(D3DVALUE
); elts
+= 1; break;
893 case D3DFVF_XYZRHW
: size
+= 4 * sizeof(D3DVALUE
); elts
+= 1; break;
894 default: TRACE(" matrix weighting not handled yet...\n");
896 size
+= 2 * sizeof(D3DVALUE
) * ((d3dvtVertexType
& D3DFVF_TEXCOUNT_MASK
) >> D3DFVF_TEXCOUNT_SHIFT
);
897 elts
+= (d3dvtVertexType
& D3DFVF_TEXCOUNT_MASK
) >> D3DFVF_TEXCOUNT_SHIFT
;
899 if (elements
) *elements
= elts
;
904 void dump_flexible_vertex(DWORD d3dvtVertexType
)
906 static const flag_info flags
[] = {
908 FE(D3DFVF_RESERVED1
),
912 if (d3dvtVertexType
& D3DFVF_RESERVED0
) DPRINTF("D3DFVF_RESERVED0 ");
913 switch (d3dvtVertexType
& D3DFVF_POSITION_MASK
) {
914 #define GEN_CASE(a) case a: DPRINTF(#a " "); break
915 GEN_CASE(D3DFVF_XYZ
);
916 GEN_CASE(D3DFVF_XYZRHW
);
917 GEN_CASE(D3DFVF_XYZB1
);
918 GEN_CASE(D3DFVF_XYZB2
);
919 GEN_CASE(D3DFVF_XYZB3
);
920 GEN_CASE(D3DFVF_XYZB4
);
921 GEN_CASE(D3DFVF_XYZB5
);
923 DDRAW_dump_flags_(d3dvtVertexType
, flags
, sizeof(flags
)/sizeof(flags
[0]), FALSE
);
924 switch (d3dvtVertexType
& D3DFVF_TEXCOUNT_MASK
) {
925 GEN_CASE(D3DFVF_TEX0
);
926 GEN_CASE(D3DFVF_TEX1
);
927 GEN_CASE(D3DFVF_TEX2
);
928 GEN_CASE(D3DFVF_TEX3
);
929 GEN_CASE(D3DFVF_TEX4
);
930 GEN_CASE(D3DFVF_TEX5
);
931 GEN_CASE(D3DFVF_TEX6
);
932 GEN_CASE(D3DFVF_TEX7
);
933 GEN_CASE(D3DFVF_TEX8
);
939 /* These are the various handler used in the generic path */
940 inline static void handle_xyz(D3DVALUE
*coords
) {
943 inline static void handle_xyzrhw(D3DVALUE
*coords
) {
944 if (coords
[3] < 1e-8)
947 GLfloat w
= 1.0 / coords
[3];
949 glVertex4f(coords
[0] * w
,
955 inline static void handle_normal(D3DVALUE
*coords
) {
959 inline static void handle_diffuse_base(RenderState
*rs
, DWORD
*color
) {
960 if (rs
->alpha_blend_enable
== TRUE
) {
961 glColor4ub((*color
>> 16) & 0xFF,
962 (*color
>> 8) & 0xFF,
963 (*color
>> 0) & 0xFF,
964 (*color
>> 24) & 0xFF);
966 glColor3ub((*color
>> 16) & 0xFF,
967 (*color
>> 8) & 0xFF,
968 (*color
>> 0) & 0xFF);
972 inline static void handle_specular_base(RenderState
*rs
, DWORD
*color
) {
973 glColor4ub((*color
>> 16) & 0xFF,
974 (*color
>> 8) & 0xFF,
975 (*color
>> 0) & 0xFF,
976 (*color
>> 24) & 0xFF); /* No idea if the alpha field is really used.. */
979 inline static void handle_diffuse(RenderState
*rs
, DWORD
*color
) {
980 if (rs
->lighting_enable
== TRUE
) {
981 if (rs
->color_diffuse
== D3DMCS_COLOR1
) {
982 glColorMaterial(GL_FRONT_AND_BACK
, GL_DIFFUSE
);
983 handle_diffuse_base(rs
, color
);
985 if (rs
->color_ambient
== D3DMCS_COLOR1
) {
986 glColorMaterial(GL_FRONT_AND_BACK
, GL_AMBIENT
);
987 handle_diffuse_base(rs
, color
);
989 if ((rs
->color_specular
== D3DMCS_COLOR1
) && (rs
->specular_enable
== TRUE
)) {
990 glColorMaterial(GL_FRONT_AND_BACK
, GL_SPECULAR
);
991 handle_diffuse_base(rs
, color
);
993 if (rs
->color_emissive
== D3DMCS_COLOR1
) {
994 glColorMaterial(GL_FRONT_AND_BACK
, GL_EMISSION
);
995 handle_diffuse_base(rs
, color
);
998 handle_diffuse_base(rs
, color
);
1002 inline static void handle_specular(RenderState
*rs
, DWORD
*color
) {
1003 if (rs
->lighting_enable
== TRUE
) {
1004 if (rs
->color_diffuse
== D3DMCS_COLOR2
) {
1005 glColorMaterial(GL_FRONT_AND_BACK
, GL_DIFFUSE
);
1006 handle_specular(rs
, color
);
1008 if (rs
->color_ambient
== D3DMCS_COLOR2
) {
1009 glColorMaterial(GL_FRONT_AND_BACK
, GL_AMBIENT
);
1010 handle_specular(rs
, color
);
1012 if ((rs
->color_specular
== D3DMCS_COLOR2
) && (rs
->specular_enable
== TRUE
)) {
1013 glColorMaterial(GL_FRONT_AND_BACK
, GL_SPECULAR
);
1014 handle_specular(rs
, color
);
1016 if (rs
->color_emissive
== D3DMCS_COLOR2
) {
1017 glColorMaterial(GL_FRONT_AND_BACK
, GL_EMISSION
);
1018 handle_specular(rs
, color
);
1021 /* No else here as we do not know how to handle 'specular' on its own in any case.. */
1024 inline static void handle_diffuse_and_specular(RenderState
*rs
, DWORD
*color_d
, DWORD
*color_s
, BOOLEAN transformed
) {
1025 if (transformed
== TRUE
) {
1026 if (rs
->fog_on
== TRUE
) {
1027 /* Special case where the specular value is used to do fogging. TODO */
1029 if (rs
->specular_enable
== TRUE
) {
1030 /* Standard specular value in transformed mode. TODO */
1032 handle_diffuse_base(rs
, color_d
);
1034 if (rs
->lighting_enable
== TRUE
) {
1035 handle_diffuse(rs
, color_d
);
1036 handle_specular(rs
, color_s
);
1038 /* In that case, only put the diffuse color... */
1039 handle_diffuse_base(rs
, color_d
);
1044 inline static void handle_texture(D3DVALUE
*coords
) {
1045 glTexCoord2fv(coords
);
1047 inline static void handle_textures(D3DVALUE
*coords
, int tex_index
) {
1048 /* For the moment, draw only the first texture.. */
1049 if (tex_index
== 0) glTexCoord2fv(coords
);
1052 static void draw_primitive_strided_7(IDirect3DDeviceImpl
*This
,
1053 D3DPRIMITIVETYPE d3dptPrimitiveType
,
1054 DWORD d3dvtVertexType
,
1055 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData
,
1056 DWORD dwStartVertex
,
1057 DWORD dwVertexCount
,
1062 IDirect3DDeviceGLImpl
* glThis
= (IDirect3DDeviceGLImpl
*) This
;
1063 if (TRACE_ON(ddraw
)) {
1064 TRACE(" Vertex format : "); dump_flexible_vertex(d3dvtVertexType
);
1068 draw_primitive_handle_GL_state(This
,
1069 (d3dvtVertexType
& D3DFVF_POSITION_MASK
) != D3DFVF_XYZ
,
1070 (d3dvtVertexType
& D3DFVF_NORMAL
) == 0);
1071 draw_primitive_start_GL(d3dptPrimitiveType
);
1073 /* Some fast paths first before the generic case.... */
1074 if (d3dvtVertexType
== D3DFVF_VERTEX
) {
1077 for (index
= 0; index
< dwIndexCount
; index
++) {
1078 int i
= (dwIndices
== NULL
) ? index
: dwIndices
[index
];
1080 (D3DVALUE
*) (((char *) lpD3DDrawPrimStrideData
->normal
.lpvData
) + i
* lpD3DDrawPrimStrideData
->normal
.dwStride
);
1081 D3DVALUE
*tex_coord
=
1082 (D3DVALUE
*) (((char *) lpD3DDrawPrimStrideData
->textureCoords
[0].lpvData
) + i
* lpD3DDrawPrimStrideData
->textureCoords
[0].dwStride
);
1083 D3DVALUE
*position
=
1084 (D3DVALUE
*) (((char *) lpD3DDrawPrimStrideData
->position
.lpvData
) + i
* lpD3DDrawPrimStrideData
->position
.dwStride
);
1086 handle_normal(normal
);
1087 handle_texture(tex_coord
);
1088 handle_xyz(position
);
1090 TRACE(" %f %f %f / %f %f %f (%f %f)\n",
1091 position
[0], position
[1], position
[2],
1092 normal
[0], normal
[1], normal
[2],
1093 tex_coord
[0], tex_coord
[1]);
1095 } else if (d3dvtVertexType
== D3DFVF_TLVERTEX
) {
1098 for (index
= 0; index
< dwIndexCount
; index
++) {
1099 int i
= (dwIndices
== NULL
) ? index
: dwIndices
[index
];
1101 (DWORD
*) (((char *) lpD3DDrawPrimStrideData
->diffuse
.lpvData
) + i
* lpD3DDrawPrimStrideData
->diffuse
.dwStride
);
1103 (DWORD
*) (((char *) lpD3DDrawPrimStrideData
->specular
.lpvData
) + i
* lpD3DDrawPrimStrideData
->specular
.dwStride
);
1104 D3DVALUE
*tex_coord
=
1105 (D3DVALUE
*) (((char *) lpD3DDrawPrimStrideData
->textureCoords
[0].lpvData
) + i
* lpD3DDrawPrimStrideData
->textureCoords
[0].dwStride
);
1106 D3DVALUE
*position
=
1107 (D3DVALUE
*) (((char *) lpD3DDrawPrimStrideData
->position
.lpvData
) + i
* lpD3DDrawPrimStrideData
->position
.dwStride
);
1109 handle_diffuse_and_specular(&(glThis
->render_state
), color_d
, color_s
, TRUE
);
1110 handle_texture(tex_coord
);
1111 handle_xyzrhw(position
);
1113 TRACE(" %f %f %f %f / %02lx %02lx %02lx %02lx - %02lx %02lx %02lx %02lx (%f %f)\n",
1114 position
[0], position
[1], position
[2], position
[3],
1115 (*color_d
>> 16) & 0xFF,
1116 (*color_d
>> 8) & 0xFF,
1117 (*color_d
>> 0) & 0xFF,
1118 (*color_d
>> 24) & 0xFF,
1119 (*color_s
>> 16) & 0xFF,
1120 (*color_s
>> 8) & 0xFF,
1121 (*color_s
>> 0) & 0xFF,
1122 (*color_s
>> 24) & 0xFF,
1123 tex_coord
[0], tex_coord
[1]);
1125 } else if (((d3dvtVertexType
& D3DFVF_POSITION_MASK
) == D3DFVF_XYZ
) ||
1126 ((d3dvtVertexType
& D3DFVF_POSITION_MASK
) == D3DFVF_XYZRHW
)) {
1127 /* This is the 'slow path' but that should support all possible vertex formats out there...
1128 Note that people should write a fast path for all vertex formats out there...
1131 for (index
= 0; index
< dwIndexCount
; index
++) {
1132 int i
= (dwIndices
== NULL
) ? index
: dwIndices
[index
];
1134 if (d3dvtVertexType
& D3DFVF_NORMAL
) {
1136 (D3DVALUE
*) (((char *) lpD3DDrawPrimStrideData
->normal
.lpvData
) + i
* lpD3DDrawPrimStrideData
->normal
.dwStride
);
1137 handle_normal(normal
);
1139 if ((d3dvtVertexType
& (D3DFVF_DIFFUSE
|D3DFVF_SPECULAR
)) == (D3DFVF_DIFFUSE
|D3DFVF_SPECULAR
)) {
1141 (DWORD
*) (((char *) lpD3DDrawPrimStrideData
->diffuse
.lpvData
) + i
* lpD3DDrawPrimStrideData
->diffuse
.dwStride
);
1143 (DWORD
*) (((char *) lpD3DDrawPrimStrideData
->specular
.lpvData
) + i
* lpD3DDrawPrimStrideData
->specular
.dwStride
);
1144 handle_diffuse_and_specular(&(glThis
->render_state
), color_d
, color_s
, (d3dvtVertexType
& D3DFVF_POSITION_MASK
) == D3DFVF_XYZRHW
);
1146 if (d3dvtVertexType
& D3DFVF_SPECULAR
) {
1148 (DWORD
*) (((char *) lpD3DDrawPrimStrideData
->specular
.lpvData
) + i
* lpD3DDrawPrimStrideData
->specular
.dwStride
);
1149 handle_specular(&(glThis
->render_state
), color_s
);
1150 } else if (d3dvtVertexType
& D3DFVF_DIFFUSE
) {
1152 (DWORD
*) (((char *) lpD3DDrawPrimStrideData
->diffuse
.lpvData
) + i
* lpD3DDrawPrimStrideData
->diffuse
.dwStride
);
1153 handle_diffuse(&(glThis
->render_state
), color_d
);
1157 if (((d3dvtVertexType
& D3DFVF_TEXCOUNT_MASK
) >> D3DFVF_TEXCOUNT_SHIFT
) == 1) {
1158 /* Special case for single texture... */
1159 D3DVALUE
*tex_coord
=
1160 (D3DVALUE
*) (((char *) lpD3DDrawPrimStrideData
->textureCoords
[0].lpvData
) + i
* lpD3DDrawPrimStrideData
->textureCoords
[0].dwStride
);
1161 handle_texture(tex_coord
);
1164 for (tex_index
= 0; tex_index
< ((d3dvtVertexType
& D3DFVF_TEXCOUNT_MASK
) >> D3DFVF_TEXCOUNT_SHIFT
); tex_index
++) {
1165 D3DVALUE
*tex_coord
=
1166 (D3DVALUE
*) (((char *) lpD3DDrawPrimStrideData
->textureCoords
[tex_index
].lpvData
) +
1167 i
* lpD3DDrawPrimStrideData
->textureCoords
[tex_index
].dwStride
);
1168 handle_textures(tex_coord
, tex_index
);
1171 if ((d3dvtVertexType
& D3DFVF_POSITION_MASK
) == D3DFVF_XYZ
) {
1172 D3DVALUE
*position
=
1173 (D3DVALUE
*) (((char *) lpD3DDrawPrimStrideData
->position
.lpvData
) + i
* lpD3DDrawPrimStrideData
->position
.dwStride
);
1174 handle_xyz(position
);
1175 } else if ((d3dvtVertexType
& D3DFVF_POSITION_MASK
) == D3DFVF_XYZRHW
) {
1176 D3DVALUE
*position
=
1177 (D3DVALUE
*) (((char *) lpD3DDrawPrimStrideData
->position
.lpvData
) + i
* lpD3DDrawPrimStrideData
->position
.dwStride
);
1178 handle_xyzrhw(position
);
1181 if (TRACE_ON(ddraw
)) {
1184 if ((d3dvtVertexType
& D3DFVF_POSITION_MASK
) == D3DFVF_XYZ
) {
1185 D3DVALUE
*position
=
1186 (D3DVALUE
*) (((char *) lpD3DDrawPrimStrideData
->position
.lpvData
) + i
* lpD3DDrawPrimStrideData
->position
.dwStride
);
1187 TRACE(" %f %f %f", position
[0], position
[1], position
[2]);
1188 } else if ((d3dvtVertexType
& D3DFVF_POSITION_MASK
) == D3DFVF_XYZRHW
) {
1189 D3DVALUE
*position
=
1190 (D3DVALUE
*) (((char *) lpD3DDrawPrimStrideData
->position
.lpvData
) + i
* lpD3DDrawPrimStrideData
->position
.dwStride
);
1191 TRACE(" %f %f %f %f", position
[0], position
[1], position
[2], position
[3]);
1193 if (d3dvtVertexType
& D3DFVF_NORMAL
) {
1195 (D3DVALUE
*) (((char *) lpD3DDrawPrimStrideData
->normal
.lpvData
) + i
* lpD3DDrawPrimStrideData
->normal
.dwStride
);
1196 DPRINTF(" / %f %f %f", normal
[0], normal
[1], normal
[2]);
1198 if (d3dvtVertexType
& D3DFVF_DIFFUSE
) {
1200 (DWORD
*) (((char *) lpD3DDrawPrimStrideData
->diffuse
.lpvData
) + i
* lpD3DDrawPrimStrideData
->diffuse
.dwStride
);
1201 DPRINTF(" / %02lx %02lx %02lx %02lx",
1202 (*color_d
>> 16) & 0xFF,
1203 (*color_d
>> 8) & 0xFF,
1204 (*color_d
>> 0) & 0xFF,
1205 (*color_d
>> 24) & 0xFF);
1207 if (d3dvtVertexType
& D3DFVF_SPECULAR
) {
1209 (DWORD
*) (((char *) lpD3DDrawPrimStrideData
->specular
.lpvData
) + i
* lpD3DDrawPrimStrideData
->specular
.dwStride
);
1210 DPRINTF(" / %02lx %02lx %02lx %02lx",
1211 (*color_s
>> 16) & 0xFF,
1212 (*color_s
>> 8) & 0xFF,
1213 (*color_s
>> 0) & 0xFF,
1214 (*color_s
>> 24) & 0xFF);
1216 for (tex_index
= 0; tex_index
< ((d3dvtVertexType
& D3DFVF_TEXCOUNT_MASK
) >> D3DFVF_TEXCOUNT_SHIFT
); tex_index
++) {
1217 D3DVALUE
*tex_coord
=
1218 (D3DVALUE
*) (((char *) lpD3DDrawPrimStrideData
->textureCoords
[tex_index
].lpvData
) +
1219 i
* lpD3DDrawPrimStrideData
->textureCoords
[tex_index
].dwStride
);
1220 DPRINTF(" / %f %f", tex_coord
[0], tex_coord
[1]);
1226 ERR(" matrix weighting not handled yet....\n");
1231 /* Whatever the case, disable the color material stuff */
1232 glDisable(GL_COLOR_MATERIAL
);
1238 static void draw_primitive_7(IDirect3DDeviceImpl
*This
,
1239 D3DPRIMITIVETYPE d3dptPrimitiveType
,
1240 DWORD d3dvtVertexType
,
1242 DWORD dwStartVertex
,
1243 DWORD dwVertexCount
,
1248 D3DDRAWPRIMITIVESTRIDEDDATA strided
;
1249 int current_offset
= 0;
1252 if ((d3dvtVertexType
& D3DFVF_POSITION_MASK
) == D3DFVF_XYZ
) {
1253 strided
.position
.lpvData
= lpvVertices
;
1254 current_offset
+= 3 * sizeof(D3DVALUE
);
1256 strided
.position
.lpvData
= lpvVertices
;
1257 current_offset
+= 4 * sizeof(D3DVALUE
);
1259 if (d3dvtVertexType
& D3DFVF_NORMAL
) {
1260 strided
.normal
.lpvData
= ((char *) lpvVertices
) + current_offset
;
1261 current_offset
+= 3 * sizeof(D3DVALUE
);
1263 if (d3dvtVertexType
& D3DFVF_DIFFUSE
) {
1264 strided
.diffuse
.lpvData
= ((char *) lpvVertices
) + current_offset
;
1265 current_offset
+= sizeof(DWORD
);
1267 if (d3dvtVertexType
& D3DFVF_SPECULAR
) {
1268 strided
.specular
.lpvData
= ((char *) lpvVertices
) + current_offset
;
1269 current_offset
+= sizeof(DWORD
);
1271 for (tex_index
= 0; tex_index
< ((d3dvtVertexType
& D3DFVF_TEXCOUNT_MASK
) >> D3DFVF_TEXCOUNT_SHIFT
); tex_index
++) {
1272 strided
.textureCoords
[tex_index
].lpvData
= ((char *) lpvVertices
) + current_offset
;
1273 current_offset
+= 2 * sizeof(D3DVALUE
);
1275 strided
.position
.dwStride
= current_offset
;
1276 strided
.normal
.dwStride
= current_offset
;
1277 strided
.diffuse
.dwStride
= current_offset
;
1278 strided
.specular
.dwStride
= current_offset
;
1279 for (tex_index
= 0; tex_index
< ((d3dvtVertexType
& D3DFVF_TEXCOUNT_MASK
) >> D3DFVF_TEXCOUNT_SHIFT
); tex_index
++)
1280 strided
.textureCoords
[tex_index
].dwStride
= current_offset
;
1282 draw_primitive_strided_7(This
, d3dptPrimitiveType
, d3dvtVertexType
, &strided
, dwStartVertex
, dwVertexCount
, dwIndices
, dwIndexCount
, dwFlags
);
1286 GL_IDirect3DDeviceImpl_7_3T_DrawPrimitive(LPDIRECT3DDEVICE7 iface
,
1287 D3DPRIMITIVETYPE d3dptPrimitiveType
,
1288 DWORD d3dvtVertexType
,
1290 DWORD dwVertexCount
,
1293 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
1294 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx)\n", This
, iface
, d3dptPrimitiveType
, d3dvtVertexType
, lpvVertices
, dwVertexCount
, dwFlags
);
1296 draw_primitive_7(This
, d3dptPrimitiveType
, d3dvtVertexType
, lpvVertices
, 0, dwVertexCount
, NULL
, dwVertexCount
, dwFlags
);
1302 GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive(LPDIRECT3DDEVICE7 iface
,
1303 D3DPRIMITIVETYPE d3dptPrimitiveType
,
1304 DWORD d3dvtVertexType
,
1306 DWORD dwVertexCount
,
1311 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
1312 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx)\n", This
, iface
, d3dptPrimitiveType
, d3dvtVertexType
, lpvVertices
, dwVertexCount
, dwIndices
, dwIndexCount
, dwFlags
);
1314 draw_primitive_7(This
, d3dptPrimitiveType
, d3dvtVertexType
, lpvVertices
, 0, dwVertexCount
, dwIndices
, dwIndexCount
, dwFlags
);
1320 GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveStrided(LPDIRECT3DDEVICE7 iface
,
1321 D3DPRIMITIVETYPE d3dptPrimitiveType
,
1323 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData
,
1324 DWORD dwVertexCount
,
1327 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
1328 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx)\n", This
, iface
, d3dptPrimitiveType
, dwVertexType
, lpD3DDrawPrimStrideData
, dwVertexCount
, dwFlags
);
1329 draw_primitive_strided_7(This
, d3dptPrimitiveType
, dwVertexType
, lpD3DDrawPrimStrideData
, 0, dwVertexCount
, NULL
, dwVertexCount
, dwFlags
);
1334 GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveStrided(LPDIRECT3DDEVICE7 iface
,
1335 D3DPRIMITIVETYPE d3dptPrimitiveType
,
1337 LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData
,
1338 DWORD dwVertexCount
,
1343 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
1344 TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx)\n", This
, iface
, d3dptPrimitiveType
, dwVertexType
, lpD3DDrawPrimStrideData
, dwVertexCount
, lpIndex
, dwIndexCount
, dwFlags
);
1345 draw_primitive_strided_7(This
, d3dptPrimitiveType
, dwVertexType
, lpD3DDrawPrimStrideData
, 0, dwVertexCount
, lpIndex
, dwIndexCount
, dwFlags
);
1350 GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveVB(LPDIRECT3DDEVICE7 iface
,
1351 D3DPRIMITIVETYPE d3dptPrimitiveType
,
1352 LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuf
,
1353 DWORD dwStartVertex
,
1354 DWORD dwNumVertices
,
1357 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
1358 IDirect3DVertexBufferImpl
*vb_impl
= ICOM_OBJECT(IDirect3DVertexBufferImpl
, IDirect3DVertexBuffer7
, lpD3DVertexBuf
);
1360 TRACE("(%p/%p)->(%08x,%p,%08lx,%08lx,%08lx)\n", This
, iface
, d3dptPrimitiveType
, lpD3DVertexBuf
, dwStartVertex
, dwNumVertices
, dwFlags
);
1362 draw_primitive_7(This
, d3dptPrimitiveType
, vb_impl
->desc
.dwFVF
, vb_impl
->vertices
, dwStartVertex
, dwNumVertices
, NULL
, dwNumVertices
, dwFlags
);
1368 GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveVB(LPDIRECT3DDEVICE7 iface
,
1369 D3DPRIMITIVETYPE d3dptPrimitiveType
,
1370 LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuf
,
1371 DWORD dwStartVertex
,
1372 DWORD dwNumVertices
,
1377 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
1378 IDirect3DVertexBufferImpl
*vb_impl
= ICOM_OBJECT(IDirect3DVertexBufferImpl
, IDirect3DVertexBuffer7
, lpD3DVertexBuf
);
1380 TRACE("(%p/%p)->(%08x,%p,%08lx,%08lx,%p,%08lx,%08lx)\n", This
, iface
, d3dptPrimitiveType
, lpD3DVertexBuf
, dwStartVertex
, dwNumVertices
, lpwIndices
, dwIndexCount
, dwFlags
);
1382 draw_primitive_7(This
, d3dptPrimitiveType
, vb_impl
->desc
.dwFVF
, vb_impl
->vertices
, dwStartVertex
, dwNumVertices
, lpwIndices
, dwIndexCount
, dwFlags
);
1388 GL_IDirect3DDeviceImpl_7_3T_SetTextureStageState(LPDIRECT3DDEVICE7 iface
,
1390 D3DTEXTURESTAGESTATETYPE d3dTexStageStateType
,
1393 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
1394 IDirect3DDeviceGLImpl
*glThis
= (IDirect3DDeviceGLImpl
*) This
;
1397 TRACE("(%p/%p)->(%08lx,%08x,%08lx)\n", This
, iface
, dwStage
, d3dTexStageStateType
, dwState
);
1399 if (TRACE_ON(ddraw
)) {
1400 TRACE(" Stage type is : ");
1401 switch (d3dTexStageStateType
) {
1402 #define GEN_CASE(a) case a: DPRINTF(#a " "); break
1403 GEN_CASE(D3DTSS_COLOROP
);
1404 GEN_CASE(D3DTSS_COLORARG1
);
1405 GEN_CASE(D3DTSS_COLORARG2
);
1406 GEN_CASE(D3DTSS_ALPHAOP
);
1407 GEN_CASE(D3DTSS_ALPHAARG1
);
1408 GEN_CASE(D3DTSS_ALPHAARG2
);
1409 GEN_CASE(D3DTSS_BUMPENVMAT00
);
1410 GEN_CASE(D3DTSS_BUMPENVMAT01
);
1411 GEN_CASE(D3DTSS_BUMPENVMAT10
);
1412 GEN_CASE(D3DTSS_BUMPENVMAT11
);
1413 GEN_CASE(D3DTSS_TEXCOORDINDEX
);
1414 GEN_CASE(D3DTSS_ADDRESS
);
1415 GEN_CASE(D3DTSS_ADDRESSU
);
1416 GEN_CASE(D3DTSS_ADDRESSV
);
1417 GEN_CASE(D3DTSS_BORDERCOLOR
);
1418 GEN_CASE(D3DTSS_MAGFILTER
);
1419 GEN_CASE(D3DTSS_MINFILTER
);
1420 GEN_CASE(D3DTSS_MIPFILTER
);
1421 GEN_CASE(D3DTSS_MIPMAPLODBIAS
);
1422 GEN_CASE(D3DTSS_MAXMIPLEVEL
);
1423 GEN_CASE(D3DTSS_MAXANISOTROPY
);
1424 GEN_CASE(D3DTSS_BUMPENVLSCALE
);
1425 GEN_CASE(D3DTSS_BUMPENVLOFFSET
);
1426 GEN_CASE(D3DTSS_TEXTURETRANSFORMFLAGS
);
1428 default: DPRINTF("UNKNOWN !!!");
1433 switch (d3dTexStageStateType
) {
1434 case D3DTSS_MINFILTER
:
1435 switch ((D3DTEXTUREMINFILTER
) dwState
) {
1437 if (TRACE_ON(ddraw
)) DPRINTF("D3DTFN_POINT\n");
1438 gl_state
= GL_NEAREST
;
1441 if (TRACE_ON(ddraw
)) DPRINTF("D3DTFN_LINEAR\n");
1442 gl_state
= GL_LINEAR
;
1445 if (TRACE_ON(ddraw
)) DPRINTF(" state unhandled (%ld).\n", dwState
);
1446 gl_state
= GL_LINEAR
;
1449 glThis
->render_state
.min
= gl_state
;
1450 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, gl_state
);
1453 case D3DTSS_MAGFILTER
:
1454 switch ((D3DTEXTUREMAGFILTER
) dwState
) {
1456 if (TRACE_ON(ddraw
)) DPRINTF("D3DTFG_POINT\n");
1457 gl_state
= GL_NEAREST
;
1460 if (TRACE_ON(ddraw
)) DPRINTF("D3DTFG_LINEAR\n");
1461 gl_state
= GL_LINEAR
;
1464 if (TRACE_ON(ddraw
)) DPRINTF(" state unhandled (%ld).\n", dwState
);
1465 gl_state
= GL_LINEAR
;
1468 glThis
->render_state
.mag
= gl_state
;
1469 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, gl_state
);
1472 case D3DTSS_ADDRESS
:
1473 case D3DTSS_ADDRESSU
:
1474 case D3DTSS_ADDRESSV
: {
1475 GLenum arg
= GL_REPEAT
; /* Default value */
1476 switch ((D3DTEXTUREADDRESS
) dwState
) {
1477 case D3DTADDRESS_WRAP
: if (TRACE_ON(ddraw
)) DPRINTF("D3DTADDRESS_WRAP\n"); arg
= GL_REPEAT
; break;
1478 case D3DTADDRESS_CLAMP
: if (TRACE_ON(ddraw
)) DPRINTF("D3DTADDRESS_CLAMP\n"); arg
= GL_CLAMP
; break;
1479 case D3DTADDRESS_BORDER
: if (TRACE_ON(ddraw
)) DPRINTF("D3DTADDRESS_BORDER\n"); arg
= GL_CLAMP_TO_EDGE
; break;
1480 default: DPRINTF(" state unhandled (%ld).\n", dwState
);
1482 if ((d3dTexStageStateType
== D3DTSS_ADDRESS
) ||
1483 (d3dTexStageStateType
== D3DTSS_ADDRESSU
))
1484 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, arg
);
1485 if ((d3dTexStageStateType
== D3DTSS_ADDRESS
) ||
1486 (d3dTexStageStateType
== D3DTSS_ADDRESSV
))
1487 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, arg
);
1491 if (TRACE_ON(ddraw
)) DPRINTF(" unhandled.\n");
1498 GL_IDirect3DDeviceImpl_7_3T_SetTexture(LPDIRECT3DDEVICE7 iface
,
1500 LPDIRECTDRAWSURFACE7 lpTexture2
)
1502 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
1503 IDirect3DDeviceGLImpl
*glThis
= (IDirect3DDeviceGLImpl
*) This
;
1505 TRACE("(%p/%p)->(%08lx,%p)\n", This
, iface
, dwStage
, lpTexture2
);
1507 if (This
->current_texture
[dwStage
] != NULL
) {
1508 /* Seems that this is not right... Need to test in real Windows
1509 IDirect3DTexture2_Release(ICOM_INTERFACE(This->current_texture[dwStage], IDirect3DTexture2)); */
1513 if (lpTexture2
== NULL
) {
1514 TRACE(" disabling 2D texturing.\n");
1515 glBindTexture(GL_TEXTURE_2D
, 0);
1516 glDisable(GL_TEXTURE_2D
);
1518 IDirectDrawSurfaceImpl
*tex_impl
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, lpTexture2
);
1519 IDirect3DTextureGLImpl
*tex_glimpl
= (IDirect3DTextureGLImpl
*) tex_impl
->tex_private
;
1521 This
->current_texture
[dwStage
] = tex_impl
;
1522 IDirectDrawSurface7_AddRef(ICOM_INTERFACE(tex_impl
, IDirectDrawSurface7
)); /* Not sure about this either */
1524 TRACE(" activating OpenGL texture %d.\n", tex_glimpl
->tex_name
);
1526 glEnable(GL_TEXTURE_2D
);
1527 glBindTexture(GL_TEXTURE_2D
, tex_glimpl
->tex_name
);
1528 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, glThis
->render_state
.mag
);
1529 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, glThis
->render_state
.min
);
1537 GL_IDirect3DDeviceImpl_7_GetCaps(LPDIRECT3DDEVICE7 iface
,
1538 LPD3DDEVICEDESC7 lpD3DHELDevDesc
)
1540 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
1541 TRACE("(%p/%p)->(%p)\n", This
, iface
, lpD3DHELDevDesc
);
1543 fill_opengl_caps_7(lpD3DHELDevDesc
);
1545 TRACE(" returning caps : no dump function yet.\n");
1551 GL_IDirect3DDeviceImpl_7_SetMaterial(LPDIRECT3DDEVICE7 iface
,
1552 LPD3DMATERIAL7 lpMat
)
1554 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
1555 TRACE("(%p/%p)->(%p)\n", This
, iface
, lpMat
);
1557 if (TRACE_ON(ddraw
)) {
1558 TRACE(" material is : \n");
1559 dump_D3DMATERIAL7(lpMat
);
1562 This
->current_material
= *lpMat
;
1564 glMaterialfv(GL_FRONT_AND_BACK
,
1566 (float *) &(This
->current_material
.u
.diffuse
));
1567 glMaterialfv(GL_FRONT_AND_BACK
,
1569 (float *) &(This
->current_material
.u1
.ambient
));
1570 glMaterialfv(GL_FRONT_AND_BACK
,
1572 (float *) &(This
->current_material
.u2
.specular
));
1573 glMaterialfv(GL_FRONT_AND_BACK
,
1575 (float *) &(This
->current_material
.u3
.emissive
));
1576 glMaterialf(GL_FRONT_AND_BACK
,
1578 This
->current_material
.u4
.power
); /* Not sure about this... */
1585 GL_IDirect3DDeviceImpl_7_SetLight(LPDIRECT3DDEVICE7 iface
,
1587 LPD3DLIGHT7 lpLight
)
1589 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
1590 TRACE("(%p/%p)->(%08lx,%p)\n", This
, iface
, dwLightIndex
, lpLight
);
1592 if (TRACE_ON(ddraw
)) {
1593 TRACE(" setting light : \n");
1594 dump_D3DLIGHT7(lpLight
);
1597 if (dwLightIndex
> MAX_LIGHTS
) return DDERR_INVALIDPARAMS
;
1598 This
->set_lights
|= 0x00000001 << dwLightIndex
;
1599 This
->light_parameters
[dwLightIndex
] = *lpLight
;
1601 switch (lpLight
->dltType
) {
1602 case D3DLIGHT_DIRECTIONAL
: { /* 3 */
1605 glLightfv(GL_LIGHT0
+ dwLightIndex
, GL_AMBIENT
, (float *) &(lpLight
->dcvAmbient
));
1606 glLightfv(GL_LIGHT0
+ dwLightIndex
, GL_DIFFUSE
, (float *) &(lpLight
->dcvDiffuse
));
1607 glLightfv(GL_LIGHT0
+ dwLightIndex
, GL_SPECULAR
, (float *) &(lpLight
->dcvSpecular
));
1609 direction
[0] = lpLight
->dvDirection
.u1
.x
;
1610 direction
[1] = lpLight
->dvDirection
.u2
.y
;
1611 direction
[2] = lpLight
->dvDirection
.u3
.z
;
1612 direction
[3] = 0.0; /* This is a directional light */
1614 glLightfv(GL_LIGHT0
+ dwLightIndex
, GL_POSITION
, (float *) direction
);
1617 default: WARN(" light type not handled yet...\n");
1624 GL_IDirect3DDeviceImpl_7_LightEnable(LPDIRECT3DDEVICE7 iface
,
1628 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
1629 TRACE("(%p/%p)->(%08lx,%d)\n", This
, iface
, dwLightIndex
, bEnable
);
1631 if (dwLightIndex
> MAX_LIGHTS
) return DDERR_INVALIDPARAMS
;
1634 if (((0x00000001 << dwLightIndex
) & This
->set_lights
) == 0) {
1635 /* Set the default parameters.. */
1636 TRACE(" setting default light parameters...\n");
1637 GL_IDirect3DDeviceImpl_7_SetLight(iface
, dwLightIndex
, &(This
->light_parameters
[dwLightIndex
]));
1639 glEnable(GL_LIGHT0
+ dwLightIndex
);
1641 glDisable(GL_LIGHT0
+ dwLightIndex
);
1647 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1648 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice7.fun))
1650 # define XCAST(fun) (void*)
1653 ICOM_VTABLE(IDirect3DDevice7
) VTABLE_IDirect3DDevice7
=
1655 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1656 XCAST(QueryInterface
) Main_IDirect3DDeviceImpl_7_3T_2T_1T_QueryInterface
,
1657 XCAST(AddRef
) Main_IDirect3DDeviceImpl_7_3T_2T_1T_AddRef
,
1658 XCAST(Release
) GL_IDirect3DDeviceImpl_7_3T_2T_1T_Release
,
1659 XCAST(GetCaps
) GL_IDirect3DDeviceImpl_7_GetCaps
,
1660 XCAST(EnumTextureFormats
) GL_IDirect3DDeviceImpl_7_3T_EnumTextureFormats
,
1661 XCAST(BeginScene
) Main_IDirect3DDeviceImpl_7_3T_2T_1T_BeginScene
,
1662 XCAST(EndScene
) Main_IDirect3DDeviceImpl_7_3T_2T_1T_EndScene
,
1663 XCAST(GetDirect3D
) Main_IDirect3DDeviceImpl_7_3T_2T_1T_GetDirect3D
,
1664 XCAST(SetRenderTarget
) Main_IDirect3DDeviceImpl_7_3T_2T_SetRenderTarget
,
1665 XCAST(GetRenderTarget
) Main_IDirect3DDeviceImpl_7_3T_2T_GetRenderTarget
,
1666 XCAST(Clear
) Main_IDirect3DDeviceImpl_7_Clear
,
1667 XCAST(SetTransform
) GL_IDirect3DDeviceImpl_7_3T_2T_SetTransform
,
1668 XCAST(GetTransform
) Main_IDirect3DDeviceImpl_7_3T_2T_GetTransform
,
1669 XCAST(SetViewport
) Main_IDirect3DDeviceImpl_7_SetViewport
,
1670 XCAST(MultiplyTransform
) Main_IDirect3DDeviceImpl_7_3T_2T_MultiplyTransform
,
1671 XCAST(GetViewport
) Main_IDirect3DDeviceImpl_7_GetViewport
,
1672 XCAST(SetMaterial
) GL_IDirect3DDeviceImpl_7_SetMaterial
,
1673 XCAST(GetMaterial
) Main_IDirect3DDeviceImpl_7_GetMaterial
,
1674 XCAST(SetLight
) GL_IDirect3DDeviceImpl_7_SetLight
,
1675 XCAST(GetLight
) Main_IDirect3DDeviceImpl_7_GetLight
,
1676 XCAST(SetRenderState
) GL_IDirect3DDeviceImpl_7_3T_2T_SetRenderState
,
1677 XCAST(GetRenderState
) Main_IDirect3DDeviceImpl_7_3T_2T_GetRenderState
,
1678 XCAST(BeginStateBlock
) Main_IDirect3DDeviceImpl_7_BeginStateBlock
,
1679 XCAST(EndStateBlock
) Main_IDirect3DDeviceImpl_7_EndStateBlock
,
1680 XCAST(PreLoad
) Main_IDirect3DDeviceImpl_7_PreLoad
,
1681 XCAST(DrawPrimitive
) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitive
,
1682 XCAST(DrawIndexedPrimitive
) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive
,
1683 XCAST(SetClipStatus
) Main_IDirect3DDeviceImpl_7_3T_2T_SetClipStatus
,
1684 XCAST(GetClipStatus
) Main_IDirect3DDeviceImpl_7_3T_2T_GetClipStatus
,
1685 XCAST(DrawPrimitiveStrided
) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveStrided
,
1686 XCAST(DrawIndexedPrimitiveStrided
) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveStrided
,
1687 XCAST(DrawPrimitiveVB
) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveVB
,
1688 XCAST(DrawIndexedPrimitiveVB
) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveVB
,
1689 XCAST(ComputeSphereVisibility
) Main_IDirect3DDeviceImpl_7_3T_ComputeSphereVisibility
,
1690 XCAST(GetTexture
) Main_IDirect3DDeviceImpl_7_3T_GetTexture
,
1691 XCAST(SetTexture
) GL_IDirect3DDeviceImpl_7_3T_SetTexture
,
1692 XCAST(GetTextureStageState
) Main_IDirect3DDeviceImpl_7_3T_GetTextureStageState
,
1693 XCAST(SetTextureStageState
) GL_IDirect3DDeviceImpl_7_3T_SetTextureStageState
,
1694 XCAST(ValidateDevice
) Main_IDirect3DDeviceImpl_7_3T_ValidateDevice
,
1695 XCAST(ApplyStateBlock
) Main_IDirect3DDeviceImpl_7_ApplyStateBlock
,
1696 XCAST(CaptureStateBlock
) Main_IDirect3DDeviceImpl_7_CaptureStateBlock
,
1697 XCAST(DeleteStateBlock
) Main_IDirect3DDeviceImpl_7_DeleteStateBlock
,
1698 XCAST(CreateStateBlock
) Main_IDirect3DDeviceImpl_7_CreateStateBlock
,
1699 XCAST(Load
) Main_IDirect3DDeviceImpl_7_Load
,
1700 XCAST(LightEnable
) GL_IDirect3DDeviceImpl_7_LightEnable
,
1701 XCAST(GetLightEnable
) Main_IDirect3DDeviceImpl_7_GetLightEnable
,
1702 XCAST(SetClipPlane
) Main_IDirect3DDeviceImpl_7_SetClipPlane
,
1703 XCAST(GetClipPlane
) Main_IDirect3DDeviceImpl_7_GetClipPlane
,
1704 XCAST(GetInfo
) Main_IDirect3DDeviceImpl_7_GetInfo
,
1707 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1712 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1713 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice3.fun))
1715 # define XCAST(fun) (void*)
1718 ICOM_VTABLE(IDirect3DDevice3
) VTABLE_IDirect3DDevice3
=
1720 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1721 XCAST(QueryInterface
) Thunk_IDirect3DDeviceImpl_3_QueryInterface
,
1722 XCAST(AddRef
) Thunk_IDirect3DDeviceImpl_3_AddRef
,
1723 XCAST(Release
) Thunk_IDirect3DDeviceImpl_3_Release
,
1724 XCAST(GetCaps
) GL_IDirect3DDeviceImpl_3_2T_1T_GetCaps
,
1725 XCAST(GetStats
) Main_IDirect3DDeviceImpl_3_2T_1T_GetStats
,
1726 XCAST(AddViewport
) Main_IDirect3DDeviceImpl_3_2T_1T_AddViewport
,
1727 XCAST(DeleteViewport
) Main_IDirect3DDeviceImpl_3_2T_1T_DeleteViewport
,
1728 XCAST(NextViewport
) Main_IDirect3DDeviceImpl_3_2T_1T_NextViewport
,
1729 XCAST(EnumTextureFormats
) Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats
,
1730 XCAST(BeginScene
) Thunk_IDirect3DDeviceImpl_3_BeginScene
,
1731 XCAST(EndScene
) Thunk_IDirect3DDeviceImpl_3_EndScene
,
1732 XCAST(GetDirect3D
) Thunk_IDirect3DDeviceImpl_3_GetDirect3D
,
1733 XCAST(SetCurrentViewport
) Main_IDirect3DDeviceImpl_3_2T_SetCurrentViewport
,
1734 XCAST(GetCurrentViewport
) Main_IDirect3DDeviceImpl_3_2T_GetCurrentViewport
,
1735 XCAST(SetRenderTarget
) Thunk_IDirect3DDeviceImpl_3_SetRenderTarget
,
1736 XCAST(GetRenderTarget
) Thunk_IDirect3DDeviceImpl_3_GetRenderTarget
,
1737 XCAST(Begin
) Main_IDirect3DDeviceImpl_3_Begin
,
1738 XCAST(BeginIndexed
) Main_IDirect3DDeviceImpl_3_BeginIndexed
,
1739 XCAST(Vertex
) Main_IDirect3DDeviceImpl_3_2T_Vertex
,
1740 XCAST(Index
) Main_IDirect3DDeviceImpl_3_2T_Index
,
1741 XCAST(End
) Main_IDirect3DDeviceImpl_3_2T_End
,
1742 XCAST(GetRenderState
) Thunk_IDirect3DDeviceImpl_3_GetRenderState
,
1743 XCAST(SetRenderState
) Thunk_IDirect3DDeviceImpl_3_SetRenderState
,
1744 XCAST(GetLightState
) Main_IDirect3DDeviceImpl_3_2T_GetLightState
,
1745 XCAST(SetLightState
) GL_IDirect3DDeviceImpl_3_2T_SetLightState
,
1746 XCAST(SetTransform
) Thunk_IDirect3DDeviceImpl_3_SetTransform
,
1747 XCAST(GetTransform
) Thunk_IDirect3DDeviceImpl_3_GetTransform
,
1748 XCAST(MultiplyTransform
) Thunk_IDirect3DDeviceImpl_3_MultiplyTransform
,
1749 XCAST(DrawPrimitive
) Thunk_IDirect3DDeviceImpl_3_DrawPrimitive
,
1750 XCAST(DrawIndexedPrimitive
) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive
,
1751 XCAST(SetClipStatus
) Thunk_IDirect3DDeviceImpl_3_SetClipStatus
,
1752 XCAST(GetClipStatus
) Thunk_IDirect3DDeviceImpl_3_GetClipStatus
,
1753 XCAST(DrawPrimitiveStrided
) Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided
,
1754 XCAST(DrawIndexedPrimitiveStrided
) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided
,
1755 XCAST(DrawPrimitiveVB
) Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB
,
1756 XCAST(DrawIndexedPrimitiveVB
) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB
,
1757 XCAST(ComputeSphereVisibility
) Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility
,
1758 XCAST(GetTexture
) Thunk_IDirect3DDeviceImpl_3_GetTexture
,
1759 XCAST(SetTexture
) Thunk_IDirect3DDeviceImpl_3_SetTexture
,
1760 XCAST(GetTextureStageState
) Thunk_IDirect3DDeviceImpl_3_GetTextureStageState
,
1761 XCAST(SetTextureStageState
) Thunk_IDirect3DDeviceImpl_3_SetTextureStageState
,
1762 XCAST(ValidateDevice
) Thunk_IDirect3DDeviceImpl_3_ValidateDevice
,
1765 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1770 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1771 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice2.fun))
1773 # define XCAST(fun) (void*)
1776 ICOM_VTABLE(IDirect3DDevice2
) VTABLE_IDirect3DDevice2
=
1778 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1779 XCAST(QueryInterface
) Thunk_IDirect3DDeviceImpl_2_QueryInterface
,
1780 XCAST(AddRef
) Thunk_IDirect3DDeviceImpl_2_AddRef
,
1781 XCAST(Release
) Thunk_IDirect3DDeviceImpl_2_Release
,
1782 XCAST(GetCaps
) Thunk_IDirect3DDeviceImpl_2_GetCaps
,
1783 XCAST(SwapTextureHandles
) Main_IDirect3DDeviceImpl_2_1T_SwapTextureHandles
,
1784 XCAST(GetStats
) Thunk_IDirect3DDeviceImpl_2_GetStats
,
1785 XCAST(AddViewport
) Thunk_IDirect3DDeviceImpl_2_AddViewport
,
1786 XCAST(DeleteViewport
) Thunk_IDirect3DDeviceImpl_2_DeleteViewport
,
1787 XCAST(NextViewport
) Thunk_IDirect3DDeviceImpl_2_NextViewport
,
1788 XCAST(EnumTextureFormats
) GL_IDirect3DDeviceImpl_2_1T_EnumTextureFormats
,
1789 XCAST(BeginScene
) Thunk_IDirect3DDeviceImpl_2_BeginScene
,
1790 XCAST(EndScene
) Thunk_IDirect3DDeviceImpl_2_EndScene
,
1791 XCAST(GetDirect3D
) Thunk_IDirect3DDeviceImpl_2_GetDirect3D
,
1792 XCAST(SetCurrentViewport
) Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport
,
1793 XCAST(GetCurrentViewport
) Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport
,
1794 XCAST(SetRenderTarget
) Thunk_IDirect3DDeviceImpl_2_SetRenderTarget
,
1795 XCAST(GetRenderTarget
) Thunk_IDirect3DDeviceImpl_2_GetRenderTarget
,
1796 XCAST(Begin
) Main_IDirect3DDeviceImpl_2_Begin
,
1797 XCAST(BeginIndexed
) Main_IDirect3DDeviceImpl_2_BeginIndexed
,
1798 XCAST(Vertex
) Thunk_IDirect3DDeviceImpl_2_Vertex
,
1799 XCAST(Index
) Thunk_IDirect3DDeviceImpl_2_Index
,
1800 XCAST(End
) Thunk_IDirect3DDeviceImpl_2_End
,
1801 XCAST(GetRenderState
) Thunk_IDirect3DDeviceImpl_2_GetRenderState
,
1802 XCAST(SetRenderState
) Thunk_IDirect3DDeviceImpl_2_SetRenderState
,
1803 XCAST(GetLightState
) Thunk_IDirect3DDeviceImpl_2_GetLightState
,
1804 XCAST(SetLightState
) Thunk_IDirect3DDeviceImpl_2_SetLightState
,
1805 XCAST(SetTransform
) Thunk_IDirect3DDeviceImpl_2_SetTransform
,
1806 XCAST(GetTransform
) Thunk_IDirect3DDeviceImpl_2_GetTransform
,
1807 XCAST(MultiplyTransform
) Thunk_IDirect3DDeviceImpl_2_MultiplyTransform
,
1808 XCAST(DrawPrimitive
) GL_IDirect3DDeviceImpl_2_DrawPrimitive
,
1809 XCAST(DrawIndexedPrimitive
) GL_IDirect3DDeviceImpl_2_DrawIndexedPrimitive
,
1810 XCAST(SetClipStatus
) Thunk_IDirect3DDeviceImpl_2_SetClipStatus
,
1811 XCAST(GetClipStatus
) Thunk_IDirect3DDeviceImpl_2_GetClipStatus
,
1814 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1819 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1820 # define XCAST(fun) (typeof(VTABLE_IDirect3DDevice.fun))
1822 # define XCAST(fun) (void*)
1825 ICOM_VTABLE(IDirect3DDevice
) VTABLE_IDirect3DDevice
=
1827 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1828 XCAST(QueryInterface
) Thunk_IDirect3DDeviceImpl_1_QueryInterface
,
1829 XCAST(AddRef
) Thunk_IDirect3DDeviceImpl_1_AddRef
,
1830 XCAST(Release
) Thunk_IDirect3DDeviceImpl_1_Release
,
1831 XCAST(Initialize
) Main_IDirect3DDeviceImpl_1_Initialize
,
1832 XCAST(GetCaps
) Thunk_IDirect3DDeviceImpl_1_GetCaps
,
1833 XCAST(SwapTextureHandles
) Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles
,
1834 XCAST(CreateExecuteBuffer
) GL_IDirect3DDeviceImpl_1_CreateExecuteBuffer
,
1835 XCAST(GetStats
) Thunk_IDirect3DDeviceImpl_1_GetStats
,
1836 XCAST(Execute
) Main_IDirect3DDeviceImpl_1_Execute
,
1837 XCAST(AddViewport
) Thunk_IDirect3DDeviceImpl_1_AddViewport
,
1838 XCAST(DeleteViewport
) Thunk_IDirect3DDeviceImpl_1_DeleteViewport
,
1839 XCAST(NextViewport
) Thunk_IDirect3DDeviceImpl_1_NextViewport
,
1840 XCAST(Pick
) Main_IDirect3DDeviceImpl_1_Pick
,
1841 XCAST(GetPickRecords
) Main_IDirect3DDeviceImpl_1_GetPickRecords
,
1842 XCAST(EnumTextureFormats
) Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats
,
1843 XCAST(CreateMatrix
) Main_IDirect3DDeviceImpl_1_CreateMatrix
,
1844 XCAST(SetMatrix
) Main_IDirect3DDeviceImpl_1_SetMatrix
,
1845 XCAST(GetMatrix
) Main_IDirect3DDeviceImpl_1_GetMatrix
,
1846 XCAST(DeleteMatrix
) Main_IDirect3DDeviceImpl_1_DeleteMatrix
,
1847 XCAST(BeginScene
) Thunk_IDirect3DDeviceImpl_1_BeginScene
,
1848 XCAST(EndScene
) Thunk_IDirect3DDeviceImpl_1_EndScene
,
1849 XCAST(GetDirect3D
) Thunk_IDirect3DDeviceImpl_1_GetDirect3D
,
1852 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
1856 static HRESULT
d3ddevice_clear(IDirect3DDeviceImpl
*This
,
1865 GLfloat old_z_clear_value
;
1866 GLbitfield bitfield
= 0;
1867 GLint old_stencil_clear_value
;
1868 GLfloat old_color_clear_value
[4];
1870 TRACE("(%p)->(%08lx,%p,%08lx,%08lx,%f,%08lx)\n", This
, dwCount
, lpRects
, dwFlags
, dwColor
, dvZ
, dwStencil
);
1871 if (TRACE_ON(ddraw
)) {
1874 TRACE(" rectangles : \n");
1875 for (i
= 0; i
< dwCount
; i
++) {
1876 TRACE(" - %ld x %ld %ld x %ld\n", lpRects
[i
].u1
.x1
, lpRects
[i
].u2
.y1
, lpRects
[i
].u3
.x2
, lpRects
[i
].u4
.y2
);
1882 WARN(" Warning, this function only for now clears the whole screen...\n");
1885 /* Clears the screen */
1887 if (dwFlags
& D3DCLEAR_ZBUFFER
) {
1888 bitfield
|= GL_DEPTH_BUFFER_BIT
;
1889 glGetBooleanv(GL_DEPTH_WRITEMASK
, &ztest
);
1890 glDepthMask(GL_TRUE
); /* Enables Z writing to be sure to delete also the Z buffer */
1891 glGetFloatv(GL_DEPTH_CLEAR_VALUE
, &old_z_clear_value
);
1893 TRACE(" depth value : %f\n", dvZ
);
1895 if (dwFlags
& D3DCLEAR_STENCIL
) {
1896 bitfield
|= GL_STENCIL_BUFFER_BIT
;
1897 glGetIntegerv(GL_STENCIL_CLEAR_VALUE
, &old_stencil_clear_value
);
1898 glClearStencil(dwStencil
);
1899 TRACE(" stencil value : %ld\n", dwStencil
);
1901 if (dwFlags
& D3DCLEAR_TARGET
) {
1902 bitfield
|= GL_COLOR_BUFFER_BIT
;
1903 glGetFloatv(GL_COLOR_CLEAR_VALUE
, old_color_clear_value
);
1904 glClearColor(((dwColor
>> 16) & 0xFF) / 255.0,
1905 ((dwColor
>> 8) & 0xFF) / 255.0,
1906 ((dwColor
>> 0) & 0xFF) / 255.0,
1907 ((dwColor
>> 24) & 0xFF) / 255.0);
1908 TRACE(" color value (ARGB) : %08lx\n", dwColor
);
1913 if (dwFlags
& D3DCLEAR_ZBUFFER
) {
1915 glClearDepth(old_z_clear_value
);
1917 if (dwFlags
& D3DCLEAR_STENCIL
) {
1918 bitfield
|= GL_STENCIL_BUFFER_BIT
;
1919 glClearStencil(old_stencil_clear_value
);
1921 if (dwFlags
& D3DCLEAR_TARGET
) {
1922 bitfield
|= GL_COLOR_BUFFER_BIT
;
1923 glClearColor(old_color_clear_value
[0],
1924 old_color_clear_value
[1],
1925 old_color_clear_value
[2],
1926 old_color_clear_value
[3]);
1935 d3ddevice_blt(IDirectDrawSurfaceImpl
*This
, LPRECT rdst
,
1936 LPDIRECTDRAWSURFACE7 src
, LPRECT rsrc
,
1937 DWORD dwFlags
, LPDDBLTFX lpbltfx
)
1939 if (dwFlags
& DDBLT_COLORFILL
) {
1940 /* This is easy to handle for the D3D Device... */
1941 DWORD color
= lpbltfx
->u5
.dwFillColor
;
1942 TRACE(" executing D3D Device override.\n");
1943 d3ddevice_clear(This
->d3ddevice
, 0, NULL
, D3DCLEAR_TARGET
, color
, 0.0, 0x00000000);
1946 return DDERR_INVALIDPARAMS
;
1950 d3ddevice_bltfast(IDirectDrawSurfaceImpl
*This
, DWORD dstx
,
1951 DWORD dsty
, LPDIRECTDRAWSURFACE7 src
,
1952 LPRECT rsrc
, DWORD trans
)
1954 return DDERR_INVALIDPARAMS
;
1958 /* TODO for both these functions :
1959 - change / restore OpenGL parameters for pictures transfers in case they are ever modified
1960 by other OpenGL code in D3D
1961 - handle the case where no 'Begin / EndScene' was done between two locks
1962 - handle the rectangles in the unlock too
1963 - handle pitch correctly...
1965 static void d3ddevice_lock_update(IDirectDrawSurfaceImpl
* This
, LPCRECT pRect
, DWORD dwFlags
)
1967 /* First, check if we need to do anything */
1968 if ((This
->lastlocktype
& DDLOCK_WRITEONLY
) == 0) {
1975 glGetIntegerv(GL_READ_BUFFER
, &prev_read
);
1978 WARN(" application does a lock on a 3D surface - expect slow downs.\n");
1979 if ((This
->surface_desc
.ddsCaps
.dwCaps
& (DDSCAPS_FRONTBUFFER
|DDSCAPS_PRIMARYSURFACE
)) != 0) {
1980 /* Application wants to lock the front buffer */
1981 glReadBuffer(GL_FRONT
);
1982 } else if ((This
->surface_desc
.ddsCaps
.dwCaps
& (DDSCAPS_BACKBUFFER
)) == (DDSCAPS_BACKBUFFER
)) {
1983 /* Application wants to lock the back buffer */
1984 glReadBuffer(GL_BACK
);
1986 WARN(" do not support 3D surface locking for this surface type - trying to use default buffer.\n");
1989 if (This
->surface_desc
.u4
.ddpfPixelFormat
.u1
.dwRGBBitCount
== 16) {
1990 buffer_type
= GL_UNSIGNED_SHORT_5_6_5
;
1992 WARN(" unsupported pixel format.\n");
1996 if (pRect
== NULL
) {
1999 loc_rect
.bottom
= This
->surface_desc
.dwHeight
;
2000 loc_rect
.right
= This
->surface_desc
.dwWidth
;
2004 glReadPixels(loc_rect
.left
, loc_rect
.top
, loc_rect
.right
, loc_rect
.bottom
,
2005 GL_RGB
, buffer_type
, ((char *)This
->surface_desc
.lpSurface
2006 + loc_rect
.top
* This
->surface_desc
.u1
.lPitch
2007 + loc_rect
.left
* GET_BPP(This
->surface_desc
)));
2008 glReadBuffer(prev_read
);
2013 static void d3ddevice_unlock_update(IDirectDrawSurfaceImpl
* This
, LPCRECT pRect
)
2015 /* First, check if we need to do anything */
2016 if ((This
->lastlocktype
& DDLOCK_READONLY
) == 0) {
2022 glGetIntegerv(GL_DRAW_BUFFER
, &prev_draw
);
2024 WARN(" application does an unlock on a 3D surface - expect slow downs.\n");
2025 if ((This
->surface_desc
.ddsCaps
.dwCaps
& (DDSCAPS_FRONTBUFFER
|DDSCAPS_PRIMARYSURFACE
)) != 0) {
2026 /* Application wants to lock the front buffer */
2027 glDrawBuffer(GL_FRONT
);
2028 } else if ((This
->surface_desc
.ddsCaps
.dwCaps
& (DDSCAPS_BACKBUFFER
)) == (DDSCAPS_BACKBUFFER
)) {
2029 /* Application wants to lock the back buffer */
2030 glDrawBuffer(GL_BACK
);
2032 WARN(" do not support 3D surface unlocking for this surface type - trying to use default buffer.\n");
2035 if (This
->surface_desc
.u4
.ddpfPixelFormat
.u1
.dwRGBBitCount
== 16) {
2036 buffer_type
= GL_UNSIGNED_SHORT_5_6_5
;
2038 WARN(" unsupported pixel format.\n");
2042 glRasterPos2f(0.0, 0.0);
2043 glDrawPixels(This
->surface_desc
.dwWidth
, This
->surface_desc
.dwHeight
,
2044 GL_RGB
, buffer_type
, This
->surface_desc
.lpSurface
);
2045 glDrawBuffer(prev_draw
);
2052 d3ddevice_create(IDirect3DDeviceImpl
**obj
, IDirect3DImpl
*d3d
, IDirectDrawSurfaceImpl
*surface
)
2054 IDirect3DDeviceImpl
*object
;
2055 IDirect3DDeviceGLImpl
*gl_object
;
2056 IDirectDrawSurfaceImpl
*surf
;
2060 XVisualInfo
template;
2064 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirect3DDeviceGLImpl
));
2065 if (object
== NULL
) return DDERR_OUTOFMEMORY
;
2067 gl_object
= (IDirect3DDeviceGLImpl
*) object
;
2071 object
->surface
= surface
;
2072 object
->set_context
= set_context
;
2073 object
->clear
= d3ddevice_clear
;
2075 TRACE(" creating OpenGL device for surface = %p, d3d = %p\n", surface
, d3d
);
2077 device_context
= GetDC(surface
->ddraw_owner
->window
);
2078 gl_object
->display
= get_display(device_context
);
2079 gl_object
->drawable
= get_drawable(device_context
);
2080 ReleaseDC(surface
->ddraw_owner
->window
,device_context
);
2083 template.visualid
= (VisualID
)GetPropA( GetDesktopWindow(), "__wine_x11_visual_id" );
2084 vis
= XGetVisualInfo(gl_object
->display
, VisualIDMask
, &template, &num
);
2086 HeapFree(GetProcessHeap(), 0, object
);
2087 ERR("No visual found !\n");
2089 return DDERR_INVALIDPARAMS
;
2091 TRACE(" visual found\n");
2094 gl_object
->gl_context
= glXCreateContext(gl_object
->display
, vis
,
2097 if (gl_object
->gl_context
== NULL
) {
2098 HeapFree(GetProcessHeap(), 0, object
);
2099 ERR("Error in context creation !\n");
2101 return DDERR_INVALIDPARAMS
;
2103 TRACE(" context created (%p)\n", gl_object
->gl_context
);
2106 /* Look for the front buffer and override its surface's Flip method (if in double buffering) */
2107 for (surf
= surface
; surf
!= NULL
; surf
= surf
->surface_owner
) {
2108 if ((surf
->surface_desc
.ddsCaps
.dwCaps
&(DDSCAPS_FLIP
|DDSCAPS_FRONTBUFFER
)) == (DDSCAPS_FLIP
|DDSCAPS_FRONTBUFFER
)) {
2109 surf
->aux_ctx
= (LPVOID
) gl_object
->display
;
2110 surf
->aux_data
= (LPVOID
) gl_object
->drawable
;
2111 surf
->aux_flip
= opengl_flip
;
2116 /* We are not doing any double buffering.. Then force OpenGL to draw on the front buffer */
2118 TRACE(" no double buffering : drawing on the front buffer\n");
2122 for (surf
= surface
; surf
->prev_attached
!= NULL
; surf
= surf
->prev_attached
) ;
2123 for (; surf
!= NULL
; surf
= surf
->next_attached
) {
2124 if (((surf
->surface_desc
.ddsCaps
.dwCaps
& (DDSCAPS_3DDEVICE
)) == (DDSCAPS_3DDEVICE
)) &&
2125 ((surf
->surface_desc
.ddsCaps
.dwCaps
& (DDSCAPS_ZBUFFER
)) != (DDSCAPS_ZBUFFER
))) {
2126 /* Override the Lock / Unlock function for all these surfaces */
2127 surf
->lock_update
= d3ddevice_lock_update
;
2128 surf
->unlock_update
= d3ddevice_unlock_update
;
2129 /* And install also the blt / bltfast overrides */
2130 surf
->aux_blt
= d3ddevice_blt
;
2131 surf
->aux_bltfast
= d3ddevice_bltfast
;
2133 surf
->d3ddevice
= object
;
2136 gl_object
->render_state
.src
= GL_ONE
;
2137 gl_object
->render_state
.dst
= GL_ZERO
;
2138 gl_object
->render_state
.mag
= GL_NEAREST
;
2139 gl_object
->render_state
.min
= GL_NEAREST
;
2140 gl_object
->render_state
.alpha_ref
= 0.0; /* No actual idea about the real default value... */
2141 gl_object
->render_state
.alpha_func
= GL_ALWAYS
; /* Here either but it seems logical */
2142 gl_object
->render_state
.alpha_blend_enable
= FALSE
;
2143 gl_object
->render_state
.fog_on
= FALSE
;
2144 gl_object
->render_state
.stencil_func
= GL_ALWAYS
;
2145 gl_object
->render_state
.stencil_mask
= 0xFFFFFFFF;
2146 gl_object
->render_state
.stencil_ref
= 0;
2147 gl_object
->render_state
.stencil_enable
= FALSE
;
2148 gl_object
->render_state
.stencil_fail
= GL_KEEP
;
2149 gl_object
->render_state
.stencil_zfail
= GL_KEEP
;
2150 gl_object
->render_state
.stencil_pass
= GL_KEEP
;
2151 gl_object
->render_state
.lighting_enable
= FALSE
;
2152 gl_object
->render_state
.specular_enable
= FALSE
;
2153 gl_object
->render_state
.color_diffuse
= D3DMCS_COLOR1
;
2154 gl_object
->render_state
.color_specular
= D3DMCS_COLOR2
;
2155 gl_object
->render_state
.color_ambient
= D3DMCS_COLOR2
;
2156 gl_object
->render_state
.color_emissive
= D3DMCS_MATERIAL
;
2158 /* Set the various light parameters */
2159 for (light
= 0; light
< MAX_LIGHTS
; light
++) {
2160 /* Only set the fields that are not zero-created */
2161 object
->light_parameters
[light
].dltType
= D3DLIGHT_DIRECTIONAL
;
2162 object
->light_parameters
[light
].dcvDiffuse
.u1
.r
= 1.0;
2163 object
->light_parameters
[light
].dcvDiffuse
.u2
.g
= 1.0;
2164 object
->light_parameters
[light
].dcvDiffuse
.u3
.b
= 1.0;
2165 object
->light_parameters
[light
].dvDirection
.u3
.z
= 1.0;
2168 /* Allocate memory for the matrices */
2169 object
->world_mat
= (D3DMATRIX
*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, 16 * sizeof(float));
2170 object
->view_mat
= (D3DMATRIX
*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, 16 * sizeof(float));
2171 object
->proj_mat
= (D3DMATRIX
*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, 16 * sizeof(float));
2172 memcpy(object
->world_mat
, id_mat
, 16 * sizeof(float));
2173 memcpy(object
->view_mat
, id_mat
, 16 * sizeof(float));
2174 memcpy(object
->proj_mat
, id_mat
, 16 * sizeof(float));
2176 /* Initialisation */
2177 TRACE(" setting current context\n");
2179 object
->set_context(object
);
2181 TRACE(" current context set\n");
2182 glHint(GL_PERSPECTIVE_CORRECTION_HINT
, GL_NICEST
);
2183 glClearColor(0.0, 0.0, 0.0, 0.0);
2184 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
| GL_STENCIL_BUFFER_BIT
);
2185 glDrawBuffer(buffer
);
2186 glReadBuffer(buffer
);
2187 /* glDisable(GL_DEPTH_TEST); Need here to check for the presence of a ZBuffer and to reenable it when the ZBuffer is attached */
2190 /* fill_device_capabilities(d3d->ddraw); */
2192 ICOM_INIT_INTERFACE(object
, IDirect3DDevice
, VTABLE_IDirect3DDevice
);
2193 ICOM_INIT_INTERFACE(object
, IDirect3DDevice2
, VTABLE_IDirect3DDevice2
);
2194 ICOM_INIT_INTERFACE(object
, IDirect3DDevice3
, VTABLE_IDirect3DDevice3
);
2195 ICOM_INIT_INTERFACE(object
, IDirect3DDevice7
, VTABLE_IDirect3DDevice7
);
2199 TRACE(" creating implementation at %p.\n", *obj
);
2201 /* And finally warn D3D that this device is now present */
2202 object
->d3d
->added_device(object
->d3d
, object
);