4 This files contains all the D3D devices that Wine supports. For the moment
5 only the 'OpenGL' target is supported. */
11 #include "wine/obj_base.h"
17 #include "d3d_private.h"
19 DEFAULT_DEBUG_CHANNEL(ddraw)
21 /* Define this variable if you have an unpatched Mesa 3.0 (patches are available
22 on Mesa's home page) or version 3.1b.
24 Version 3.2b should correct this bug */
25 #undef HAVE_BUGGY_MESAGL
29 static GUID IID_D3DDEVICE2_OpenGL = {
33 { 0x8b,0x7c,0x0e,0x4e,0xd8,0x3c,0x2b,0x3c }
36 static GUID IID_D3DDEVICE_OpenGL = {
40 { 0x82,0x2d,0xa8,0xd5,0x31,0x87,0xca,0xfa }
44 static ICOM_VTABLE(IDirect3DDevice2) OpenGL_vtable;
45 static ICOM_VTABLE(IDirect3DDevice) OpenGL_vtable_dx3;
47 /*******************************************************************************
48 * OpenGL static functions
50 static void set_context(IDirect3DDevice2Impl* This) {
51 OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) This;
53 OSMesaMakeCurrent(odev->ctx, odev->buffer,
55 This->surface->s.surface_desc.dwWidth,
56 This->surface->s.surface_desc.dwHeight);
59 static void set_context_dx3(IDirect3DDeviceImpl* This) {
60 OpenGL_IDirect3DDevice *odev = (OpenGL_IDirect3DDevice *) This;
62 OSMesaMakeCurrent(odev->ctx, odev->buffer,
64 This->surface->s.surface_desc.dwWidth,
65 This->surface->s.surface_desc.dwHeight);
68 static void fill_opengl_primcaps(D3DPRIMCAPS *pc)
70 pc->dwSize = sizeof(*pc);
71 pc->dwMiscCaps = D3DPMISCCAPS_CONFORMANT | D3DPMISCCAPS_CULLCCW | D3DPMISCCAPS_CULLCW |
72 D3DPMISCCAPS_LINEPATTERNREP | D3DPMISCCAPS_MASKZ;
73 pc->dwRasterCaps = D3DPRASTERCAPS_DITHER | D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_FOGTABLE |
74 D3DPRASTERCAPS_FOGVERTEX | D3DPRASTERCAPS_STIPPLE | D3DPRASTERCAPS_ZBIAS | D3DPRASTERCAPS_ZTEST;
75 pc->dwZCmpCaps = 0xFFFFFFFF; /* All Z test can be done */
76 pc->dwSrcBlendCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
77 pc->dwDestBlendCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
78 pc->dwAlphaCmpCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
79 pc->dwShadeCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
80 pc->dwTextureCaps = D3DPTEXTURECAPS_ALPHA | D3DPTEXTURECAPS_BORDER | D3DPTEXTURECAPS_PERSPECTIVE |
81 D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_TRANSPARENCY;
82 pc->dwTextureFilterCaps = D3DPTFILTERCAPS_LINEAR | D3DPTFILTERCAPS_LINEARMIPLINEAR | D3DPTFILTERCAPS_LINEARMIPNEAREST |
83 D3DPTFILTERCAPS_MIPLINEAR | D3DPTFILTERCAPS_MIPNEAREST | D3DPTFILTERCAPS_NEAREST;
84 pc->dwTextureBlendCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
85 pc->dwTextureAddressCaps = D3DPTADDRESSCAPS_BORDER | D3DPTADDRESSCAPS_CLAMP | D3DPTADDRESSCAPS_WRAP;
86 pc->dwStippleWidth = 32;
87 pc->dwStippleHeight = 32;
90 static void fill_opengl_caps(D3DDEVICEDESC *d1, D3DDEVICEDESC *d2)
94 d1->dwSize = sizeof(*d1);
95 d1->dwFlags = D3DDD_DEVCAPS | D3DDD_BCLIPPING | D3DDD_COLORMODEL | D3DDD_DEVICERENDERBITDEPTH | D3DDD_DEVICEZBUFFERBITDEPTH
96 | D3DDD_LIGHTINGCAPS | D3DDD_LINECAPS | D3DDD_MAXBUFFERSIZE | D3DDD_MAXVERTEXCOUNT | D3DDD_TRANSFORMCAPS | D3DDD_TRICAPS;
97 d1->dcmColorModel = D3DCOLOR_RGB;
98 d1->dwDevCaps = D3DDEVCAPS_CANRENDERAFTERFLIP | D3DDEVCAPS_DRAWPRIMTLVERTEX | D3DDEVCAPS_EXECUTESYSTEMMEMORY |
99 D3DDEVCAPS_EXECUTEVIDEOMEMORY | D3DDEVCAPS_FLOATTLVERTEX | D3DDEVCAPS_TEXTURENONLOCALVIDMEM | D3DDEVCAPS_TEXTURESYSTEMMEMORY |
100 D3DDEVCAPS_TEXTUREVIDEOMEMORY | D3DDEVCAPS_TLVERTEXSYSTEMMEMORY | D3DDEVCAPS_TLVERTEXVIDEOMEMORY;
101 d1->dtcTransformCaps.dwSize = sizeof(D3DTRANSFORMCAPS);
102 d1->dtcTransformCaps.dwCaps = D3DTRANSFORMCAPS_CLIP;
103 d1->bClipping = TRUE;
104 d1->dlcLightingCaps.dwSize = sizeof(D3DLIGHTINGCAPS);
105 d1->dlcLightingCaps.dwCaps = D3DLIGHTCAPS_DIRECTIONAL | D3DLIGHTCAPS_PARALLELPOINT | D3DLIGHTCAPS_POINT | D3DLIGHTCAPS_SPOT;
106 d1->dlcLightingCaps.dwLightingModel = D3DLIGHTINGMODEL_RGB;
107 d1->dlcLightingCaps.dwNumLights = 16; /* glGetIntegerv(GL_MAX_LIGHTS, &maxlight); d1->dlcLightingCaps.dwNumLights = maxlight; */
108 fill_opengl_primcaps(&(d1->dpcLineCaps));
109 fill_opengl_primcaps(&(d1->dpcTriCaps));
110 d1->dwDeviceRenderBitDepth = DDBD_16;
111 d1->dwDeviceZBufferBitDepth = DDBD_16;
112 d1->dwMaxBufferSize = 0;
113 d1->dwMaxVertexCount = 65536;
114 d1->dwMinTextureWidth = 1;
115 d1->dwMinTextureHeight = 1;
116 d1->dwMaxTextureWidth = 256; /* This is for Mesa on top of Glide (in the future :-) ) */
117 d1->dwMaxTextureHeight = 256; /* This is for Mesa on top of Glide (in the future :-) ) */
118 d1->dwMinStippleWidth = 1;
119 d1->dwMinStippleHeight = 1;
120 d1->dwMaxStippleWidth = 32;
121 d1->dwMaxStippleHeight = 32;
123 d2->dwSize = sizeof(*d2);
127 int d3d_OpenGL(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) {
130 TRACE(ddraw," Enumerating OpenGL D3D device.\n");
132 fill_opengl_caps(&d1, &d2);
134 return cb((void*)&IID_D3DDEVICE2_OpenGL,"WINE Direct3D using OpenGL","direct3d",&d1,&d2,context);
137 int is_OpenGL(REFCLSID rguid, IDirectDrawSurfaceImpl* surface, IDirect3DDevice2Impl** device, IDirect3D2Impl* d3d)
139 if (/* Default device */
142 (!memcmp(&IID_IDirect3DHALDevice,rguid,sizeof(IID_IDirect3DHALDevice))) ||
144 (!memcmp(&IID_D3DDEVICE2_OpenGL,rguid,sizeof(IID_D3DDEVICE2_OpenGL)))) {
145 OpenGL_IDirect3DDevice2 *odev;
147 const float id_mat[16] = {
154 *device = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(OpenGL_IDirect3DDevice2));
155 odev = (OpenGL_IDirect3DDevice2 *) (*device);
157 (*device)->lpvtbl = &OpenGL_vtable;
158 (*device)->d3d = d3d;
159 (*device)->surface = surface;
161 (*device)->viewport_list = NULL;
162 (*device)->current_viewport = NULL;
164 (*device)->set_context = set_context;
166 TRACE(ddraw, "OpenGL device created \n");
168 /* Create the OpenGL context */
169 odev->ctx = OSMesaCreateContext(OSMESA_RGBA, NULL);
170 odev->buffer = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
171 surface->s.surface_desc.dwWidth * surface->s.surface_desc.dwHeight * 4);
172 odev->rs.src = GL_ONE;
173 odev->rs.dst = GL_ZERO;
174 odev->rs.mag = GL_NEAREST;
175 odev->rs.min = GL_NEAREST;
178 memcpy(odev->world_mat, id_mat, 16 * sizeof(float));
179 memcpy(odev->view_mat , id_mat, 16 * sizeof(float));
180 memcpy(odev->proj_mat , id_mat, 16 * sizeof(float));
183 (*device)->set_context(*device);
184 glClearColor(0.0, 0.0, 0.0, 0.0);
185 glColor3f(1.0, 1.0, 1.0);
190 /* This is not the OpenGL UID */
194 /*******************************************************************************
195 * Common IDirect3DDevice2
198 static HRESULT WINAPI IDirect3DDevice2Impl_QueryInterface(LPDIRECT3DDEVICE2 iface,
202 ICOM_THIS(IDirect3DDevice2Impl,iface);
205 WINE_StringFromCLSID((LPCLSID)riid,xrefiid);
206 FIXME(ddraw, "(%p)->(%s,%p): stub\n", This, xrefiid,ppvObj);
213 static ULONG WINAPI IDirect3DDevice2Impl_AddRef(LPDIRECT3DDEVICE2 iface)
215 ICOM_THIS(IDirect3DDevice2Impl,iface);
216 TRACE(ddraw, "(%p)->()incrementing from %lu.\n", This, This->ref );
218 return ++(This->ref);
223 static ULONG WINAPI IDirect3DDevice2Impl_Release(LPDIRECT3DDEVICE2 iface)
225 ICOM_THIS(IDirect3DDevice2Impl,iface);
226 FIXME( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
228 if (!--(This->ref)) {
229 HeapFree(GetProcessHeap(),0,This);
237 /*** IDirect3DDevice2 methods ***/
238 static HRESULT WINAPI IDirect3DDevice2Impl_GetCaps(LPDIRECT3DDEVICE2 iface,
239 LPD3DDEVICEDESC lpdescsoft,
240 LPD3DDEVICEDESC lpdeschard)
242 ICOM_THIS(IDirect3DDevice2Impl,iface);
243 FIXME(ddraw, "(%p)->(%p,%p): stub\n", This, lpdescsoft, lpdeschard);
245 fill_opengl_caps(lpdescsoft, lpdeschard);
252 static HRESULT WINAPI IDirect3DDevice2Impl_SwapTextureHandles(LPDIRECT3DDEVICE2 iface,
253 LPDIRECT3DTEXTURE2 lptex1,
254 LPDIRECT3DTEXTURE2 lptex2)
256 ICOM_THIS(IDirect3DDevice2Impl,iface);
257 FIXME(ddraw, "(%p)->(%p,%p): stub\n", This, lptex1, lptex2);
264 static HRESULT WINAPI IDirect3DDevice2Impl_GetStats(LPDIRECT3DDEVICE2 iface,
267 ICOM_THIS(IDirect3DDevice2Impl,iface);
268 FIXME(ddraw, "(%p)->(%p): stub\n", This, lpstats);
275 static HRESULT WINAPI IDirect3DDevice2Impl_AddViewport(LPDIRECT3DDEVICE2 iface,
276 LPDIRECT3DVIEWPORT2 lpvp)
278 ICOM_THIS(IDirect3DDevice2Impl,iface);
279 IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
280 FIXME(ddraw, "(%p)->(%p): stub\n", This, ilpvp);
282 /* Adds this viewport to the viewport list */
283 ilpvp->next = This->viewport_list;
284 This->viewport_list = ilpvp;
291 static HRESULT WINAPI IDirect3DDevice2Impl_DeleteViewport(LPDIRECT3DDEVICE2 iface,
292 LPDIRECT3DVIEWPORT2 lpvp)
294 ICOM_THIS(IDirect3DDevice2Impl,iface);
295 IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
296 IDirect3DViewport2Impl *cur, *prev;
297 FIXME(ddraw, "(%p)->(%p): stub\n", This, lpvp);
299 /* Finds this viewport in the list */
301 cur = This->viewport_list;
302 while ((cur != NULL) && (cur != ilpvp)) {
307 return DDERR_INVALIDOBJECT;
311 This->viewport_list = cur->next;
313 prev->next = cur->next;
320 static HRESULT WINAPI IDirect3DDevice2Impl_NextViewport(LPDIRECT3DDEVICE2 iface,
321 LPDIRECT3DVIEWPORT2 lpvp,
322 LPDIRECT3DVIEWPORT2* lplpvp,
325 ICOM_THIS(IDirect3DDevice2Impl,iface);
326 IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
327 IDirect3DViewport2Impl** ilplpvp=(IDirect3DViewport2Impl**)lplpvp;
328 FIXME(ddraw, "(%p)->(%p,%p,%08lx): stub\n", This, lpvp, lpvp, dwFlags);
332 *ilplpvp = ilpvp->next;
336 *ilplpvp = This->viewport_list;
340 ilpvp = This->viewport_list;
341 while (ilpvp->next != NULL)
348 return DDERR_INVALIDPARAMS;
354 static HRESULT enum_texture_format_OpenGL(LPD3DENUMTEXTUREFORMATSCALLBACK cb,
357 LPDDPIXELFORMAT pformat;
359 /* Do the texture enumeration */
360 sdesc.dwSize = sizeof(DDSURFACEDESC);
361 sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
362 sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
363 pformat = &(sdesc.ddpfPixelFormat);
364 pformat->dwSize = sizeof(DDPIXELFORMAT);
365 pformat->dwFourCC = 0;
367 TRACE(ddraw, "Enumerating GL_RGBA unpacked (32)\n");
368 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
369 pformat->x.dwRGBBitCount = 32;
370 pformat->y.dwRBitMask = 0xFF000000;
371 pformat->z.dwGBitMask = 0x00FF0000;
372 pformat->xx.dwBBitMask = 0x0000FF00;
373 pformat->xy.dwRGBAlphaBitMask = 0x000000FF;
374 if (cb(&sdesc, context) == 0)
377 TRACE(ddraw, "Enumerating GL_RGB unpacked (24)\n");
378 pformat->dwFlags = DDPF_RGB;
379 pformat->x.dwRGBBitCount = 24;
380 pformat->y.dwRBitMask = 0x00FF0000;
381 pformat->z.dwGBitMask = 0x0000FF00;
382 pformat->xx.dwBBitMask = 0x000000FF;
383 pformat->xy.dwRGBAlphaBitMask = 0x00000000;
384 if (cb(&sdesc, context) == 0)
387 #ifndef HAVE_BUGGY_MESAGL
388 /* The packed texture format are buggy in Mesa. The bug was reported and corrected,
389 so that future version will work great. */
390 TRACE(ddraw, "Enumerating GL_RGB packed GL_UNSIGNED_SHORT_5_6_5 (16)\n");
391 pformat->dwFlags = DDPF_RGB;
392 pformat->x.dwRGBBitCount = 16;
393 pformat->y.dwRBitMask = 0x0000F800;
394 pformat->z.dwGBitMask = 0x000007E0;
395 pformat->xx.dwBBitMask = 0x0000001F;
396 pformat->xy.dwRGBAlphaBitMask = 0x00000000;
397 if (cb(&sdesc, context) == 0)
400 TRACE(ddraw, "Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_5_5_5_1 (16)\n");
401 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
402 pformat->x.dwRGBBitCount = 16;
403 pformat->y.dwRBitMask = 0x0000F800;
404 pformat->z.dwGBitMask = 0x000007C0;
405 pformat->xx.dwBBitMask = 0x0000003E;
406 pformat->xy.dwRGBAlphaBitMask = 0x00000001;
407 if (cb(&sdesc, context) == 0)
410 TRACE(ddraw, "Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_4_4_4_4 (16)\n");
411 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
412 pformat->x.dwRGBBitCount = 16;
413 pformat->y.dwRBitMask = 0x0000F000;
414 pformat->z.dwGBitMask = 0x00000F00;
415 pformat->xx.dwBBitMask = 0x000000F0;
416 pformat->xy.dwRGBAlphaBitMask = 0x0000000F;
417 if (cb(&sdesc, context) == 0)
420 TRACE(ddraw, "Enumerating GL_RGB packed GL_UNSIGNED_BYTE_3_3_2 (8)\n");
421 pformat->dwFlags = DDPF_RGB;
422 pformat->x.dwRGBBitCount = 8;
423 pformat->y.dwRBitMask = 0x0000F800;
424 pformat->z.dwGBitMask = 0x000007C0;
425 pformat->xx.dwBBitMask = 0x0000003E;
426 pformat->xy.dwRGBAlphaBitMask = 0x00000001;
427 if (cb(&sdesc, context) == 0)
431 TRACE(ddraw, "Enumerating Paletted (8)\n");
432 pformat->dwFlags = DDPF_PALETTEINDEXED8;
433 pformat->x.dwRGBBitCount = 8;
434 pformat->y.dwRBitMask = 0x00000000;
435 pformat->z.dwGBitMask = 0x00000000;
436 pformat->xx.dwBBitMask = 0x00000000;
437 pformat->xy.dwRGBAlphaBitMask = 0x00000000;
438 if (cb(&sdesc, context) == 0)
441 TRACE(ddraw, "End of enumeration\n");
446 static HRESULT WINAPI IDirect3DDevice2Impl_EnumTextureFormats(LPDIRECT3DDEVICE2 iface,
447 LPD3DENUMTEXTUREFORMATSCALLBACK cb,
450 ICOM_THIS(IDirect3DDevice2Impl,iface);
451 FIXME(ddraw, "(%p)->(%p,%p): stub\n", This, cb, context);
453 return enum_texture_format_OpenGL(cb, context);
458 static HRESULT WINAPI IDirect3DDevice2Impl_BeginScene(LPDIRECT3DDEVICE2 iface)
460 ICOM_THIS(IDirect3DDevice2Impl,iface);
461 /* OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) This; */
463 FIXME(ddraw, "(%p)->(): stub\n", This);
465 /* Here, we should get the DDraw surface and 'copy it' to the
466 OpenGL surface.... */
473 static HRESULT WINAPI IDirect3DDevice2Impl_EndScene(LPDIRECT3DDEVICE2 iface)
475 ICOM_THIS(IDirect3DDevice2Impl,iface);
476 OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) This;
477 LPDIRECTDRAWSURFACE3 surf = (LPDIRECTDRAWSURFACE3) This->surface;
481 unsigned short *dest;
483 FIXME(ddraw, "(%p)->(): stub\n", This);
485 /* Here we copy back the OpenGL scene to the the DDraw surface */
486 /* First, lock the surface */
487 IDirectDrawSurface3_Lock(surf,NULL,&sdesc,DDLOCK_WRITEONLY,0);
489 /* The copy the OpenGL buffer to this surface */
491 /* NOTE : this is only for debugging purpose. I KNOW it is really unoptimal.
492 I am currently working on a set of patches for Mesa to have OSMesa support
493 16 bpp surfaces => we will able to render directly onto the surface, no
494 need to do a bpp conversion */
495 dest = (unsigned short *) sdesc.y.lpSurface;
496 src = ((unsigned char *) odev->buffer) + 4 * (sdesc.dwWidth * (sdesc.dwHeight - 1));
497 for (y = 0; y < sdesc.dwHeight; y++) {
498 unsigned char *lsrc = src;
500 for (x = 0; x < sdesc.dwWidth ; x++) {
501 unsigned char r = *lsrc++;
502 unsigned char g = *lsrc++;
503 unsigned char b = *lsrc++;
505 *dest = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
510 src -= 4 * sdesc.dwWidth;
513 /* Unlock the surface */
514 IDirectDrawSurface3_Unlock(surf,sdesc.y.lpSurface);
521 static HRESULT WINAPI IDirect3DDevice2Impl_GetDirect3D(LPDIRECT3DDEVICE2 iface, LPDIRECT3D2 *lpd3d2)
523 ICOM_THIS(IDirect3DDevice2Impl,iface);
524 TRACE(ddraw, "(%p)->(%p): stub\n", This, lpd3d2);
526 *lpd3d2 = (LPDIRECT3D2)This->d3d;
533 /*** DrawPrimitive API ***/
534 static HRESULT WINAPI IDirect3DDevice2Impl_SetCurrentViewport(LPDIRECT3DDEVICE2 iface,
535 LPDIRECT3DVIEWPORT2 lpvp)
537 ICOM_THIS(IDirect3DDevice2Impl,iface);
538 IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
539 FIXME(ddraw, "(%p)->(%p): stub\n", This, ilpvp);
541 /* Should check if the viewport was added or not */
543 /* Set this viewport as the current viewport */
544 This->current_viewport = ilpvp;
546 /* Activate this viewport */
547 ilpvp->device.active_device2 = This;
548 ilpvp->activate(ilpvp);
555 static HRESULT WINAPI IDirect3DDevice2Impl_GetCurrentViewport(LPDIRECT3DDEVICE2 iface,
556 LPDIRECT3DVIEWPORT2 *lplpvp)
558 ICOM_THIS(IDirect3DDevice2Impl,iface);
559 FIXME(ddraw, "(%p)->(%p): stub\n", This, lplpvp);
561 /* Returns the current viewport */
562 *lplpvp = (LPDIRECT3DVIEWPORT2)This->current_viewport;
569 static HRESULT WINAPI IDirect3DDevice2Impl_SetRenderTarget(LPDIRECT3DDEVICE2 iface,
570 LPDIRECTDRAWSURFACE lpdds,
573 ICOM_THIS(IDirect3DDevice2Impl,iface);
574 FIXME(ddraw, "(%p)->(%p,%08lx): stub\n", This, lpdds, dwFlags);
581 static HRESULT WINAPI IDirect3DDevice2Impl_GetRenderTarget(LPDIRECT3DDEVICE2 iface,
582 LPDIRECTDRAWSURFACE *lplpdds)
584 ICOM_THIS(IDirect3DDevice2Impl,iface);
585 FIXME(ddraw, "(%p)->(%p): stub\n", This, lplpdds);
587 /* Returns the current rendering target (the surface on wich we render) */
588 *lplpdds = (LPDIRECTDRAWSURFACE)This->surface;
595 static HRESULT WINAPI IDirect3DDevice2Impl_Begin(LPDIRECT3DDEVICE2 iface,
596 D3DPRIMITIVETYPE d3dp,
600 ICOM_THIS(IDirect3DDevice2Impl,iface);
601 FIXME(ddraw, "(%p)->(%d,%d,%08lx): stub\n", This, d3dp, d3dv, dwFlags);
608 static HRESULT WINAPI IDirect3DDevice2Impl_BeginIndexed(LPDIRECT3DDEVICE2 iface,
609 D3DPRIMITIVETYPE d3dp,
615 ICOM_THIS(IDirect3DDevice2Impl,iface);
616 FIXME(ddraw, "(%p)->(%d,%d,%p,%ld,%08lx): stub\n", This, d3dp, d3dv, lpvert, numvert, dwFlags);
623 static HRESULT WINAPI IDirect3DDevice2Impl_Vertex(LPDIRECT3DDEVICE2 iface,
626 ICOM_THIS(IDirect3DDevice2Impl,iface);
627 FIXME(ddraw, "(%p)->(%p): stub\n", This, lpvert);
634 static HRESULT WINAPI IDirect3DDevice2Impl_Index(LPDIRECT3DDEVICE2 iface,
637 ICOM_THIS(IDirect3DDevice2Impl,iface);
638 FIXME(ddraw, "(%p)->(%d): stub\n", This, index);
645 static HRESULT WINAPI IDirect3DDevice2Impl_End(LPDIRECT3DDEVICE2 iface,
648 ICOM_THIS(IDirect3DDevice2Impl,iface);
649 FIXME(ddraw, "(%p)->(%08lx): stub\n", This, dwFlags);
657 static HRESULT WINAPI IDirect3DDevice2Impl_GetRenderState(LPDIRECT3DDEVICE2 iface,
658 D3DRENDERSTATETYPE d3drs,
661 ICOM_THIS(IDirect3DDevice2Impl,iface);
662 FIXME(ddraw, "(%p)->(%d,%p): stub\n", This, d3drs, lprstate);
669 static HRESULT WINAPI IDirect3DDevice2Impl_SetRenderState(LPDIRECT3DDEVICE2 iface,
670 D3DRENDERSTATETYPE dwRenderStateType,
673 ICOM_THIS(IDirect3DDevice2Impl,iface);
674 OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) This;
676 TRACE(ddraw, "(%p)->(%d,%ld)\n", This, dwRenderStateType, dwRenderState);
678 /* Call the render state functions */
679 set_render_state(dwRenderStateType, dwRenderState, &(odev->rs));
686 static HRESULT WINAPI IDirect3DDevice2Impl_GetLightState(LPDIRECT3DDEVICE2 iface,
687 D3DLIGHTSTATETYPE d3dls,
690 ICOM_THIS(IDirect3DDevice2Impl,iface);
691 FIXME(ddraw, "(%p)->(%d,%p): stub\n", This, d3dls, lplstate);
698 static HRESULT WINAPI IDirect3DDevice2Impl_SetLightState(LPDIRECT3DDEVICE2 iface,
699 D3DLIGHTSTATETYPE dwLightStateType,
702 ICOM_THIS(IDirect3DDevice2Impl,iface);
703 FIXME(ddraw, "(%p)->(%d,%08lx): stub\n", This, dwLightStateType, dwLightState);
705 switch (dwLightStateType) {
706 case D3DLIGHTSTATE_MATERIAL: { /* 1 */
707 IDirect3DMaterial2Impl* mat = (IDirect3DMaterial2Impl*) dwLightState;
712 TRACE(ddraw, "Zoups !!!\n");
716 case D3DLIGHTSTATE_AMBIENT: { /* 2 */
719 light[0] = ((dwLightState >> 16) & 0xFF) / 255.0;
720 light[1] = ((dwLightState >> 8) & 0xFF) / 255.0;
721 light[2] = ((dwLightState >> 0) & 0xFF) / 255.0;
723 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (float *) light);
726 case D3DLIGHTSTATE_COLORMODEL: /* 3 */
729 case D3DLIGHTSTATE_FOGMODE: /* 4 */
732 case D3DLIGHTSTATE_FOGSTART: /* 5 */
735 case D3DLIGHTSTATE_FOGEND: /* 6 */
738 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */
742 TRACE(ddraw, "Unexpected Light State Type\n");
743 return DDERR_INVALIDPARAMS;
751 static HRESULT WINAPI IDirect3DDevice2Impl_SetTransform(LPDIRECT3DDEVICE2 iface,
752 D3DTRANSFORMSTATETYPE d3dts,
753 LPD3DMATRIX lpmatrix)
755 ICOM_THIS(IDirect3DDevice2Impl,iface);
756 OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) This;
758 FIXME(ddraw, "(%p)->(%d,%p): stub\n", This, d3dts, lpmatrix);
760 /* Using a trial and failure approach, I found that the order of
761 Direct3D transformations that works best is :
763 ScreenCoord = ProjectionMat * ViewMat * WorldMat * ObjectCoord
765 As OpenGL uses only two matrices, I combined PROJECTION and VIEW into
766 OpenGL's GL_PROJECTION matrix and the WORLD into GL_MODELVIEW.
768 If anyone has a good explanation of the three different matrices in
769 the SDK online documentation, feel free to point it to me. For example,
770 which matrices transform lights ? In OpenGL only the PROJECTION matrix
771 transform the lights, not the MODELVIEW. Using the matrix names, I
772 supposed that PROJECTION and VIEW (all 'camera' related names) do
773 transform lights, but WORLD do not. It may be wrong though... */
775 /* After reading through both OpenGL and Direct3D documentations, I
776 thought that D3D matrices were written in 'line major mode' transposed
777 from OpenGL's 'column major mode'. But I found out that a simple memcpy
778 works fine to transfer one matrix format to the other (it did not work
779 when transposing)....
782 1) are the documentations wrong
783 2) does the matrix work even if they are not read correctly
784 3) is Mesa's implementation of OpenGL not compliant regarding Matrix
785 loading using glLoadMatrix ?
787 Anyway, I always use 'conv_mat' to transfer the matrices from one format
788 to the other so that if I ever find out that I need to transpose them, I
789 will able to do it quickly, only by changing the macro conv_mat. */
792 case D3DTRANSFORMSTATE_WORLD: {
793 conv_mat(lpmatrix, odev->world_mat);
794 glMatrixMode(GL_MODELVIEW);
795 glLoadMatrixf((float *) &(odev->world_mat));
798 case D3DTRANSFORMSTATE_VIEW: {
799 conv_mat(lpmatrix, odev->view_mat);
800 glMatrixMode(GL_PROJECTION);
801 glLoadMatrixf((float *) &(odev->proj_mat));
802 glMultMatrixf((float *) &(odev->view_mat));
805 case D3DTRANSFORMSTATE_PROJECTION: {
806 conv_mat(lpmatrix, odev->proj_mat);
807 glMatrixMode(GL_PROJECTION);
808 glLoadMatrixf((float *) &(odev->proj_mat));
809 glMultMatrixf((float *) &(odev->view_mat));
821 static HRESULT WINAPI IDirect3DDevice2Impl_GetTransform(LPDIRECT3DDEVICE2 iface,
822 D3DTRANSFORMSTATETYPE d3dts,
823 LPD3DMATRIX lpmatrix)
825 ICOM_THIS(IDirect3DDevice2Impl,iface);
826 FIXME(ddraw, "(%p)->(%d,%p): stub\n", This, d3dts, lpmatrix);
833 static HRESULT WINAPI IDirect3DDevice2Impl_MultiplyTransform(LPDIRECT3DDEVICE2 iface,
834 D3DTRANSFORMSTATETYPE d3dts,
835 LPD3DMATRIX lpmatrix)
837 ICOM_THIS(IDirect3DDevice2Impl,iface);
838 FIXME(ddraw, "(%p)->(%d,%p): stub\n", This, d3dts, lpmatrix);
843 #define DRAW_PRIMITIVE(MAXVERT,INDEX) \
844 /* Puts GL in the correct lighting mode */ \
845 if (odev->vt != d3dv) { \
846 if (odev->vt == D3DVT_TLVERTEX) { \
847 /* Need to put the correct transformation again */ \
848 glMatrixMode(GL_MODELVIEW); \
849 glLoadMatrixf((float *) &(odev->world_mat)); \
850 glMatrixMode(GL_PROJECTION); \
851 glLoadMatrixf((float *) &(odev->proj_mat)); \
852 glMultMatrixf((float *) &(odev->view_mat)); \
857 TRACE(ddraw, "Standard Vertex\n"); \
858 glEnable(GL_LIGHTING); \
861 case D3DVT_LVERTEX: \
862 TRACE(ddraw, "Lighted Vertex\n"); \
863 glDisable(GL_LIGHTING); \
866 case D3DVT_TLVERTEX: { \
867 GLdouble height, width, minZ, maxZ; \
869 TRACE(ddraw, "Transformed - Lighted Vertex\n"); \
870 /* First, disable lighting */ \
871 glDisable(GL_LIGHTING); \
873 /* Then do not put any transformation matrixes */ \
874 glMatrixMode(GL_MODELVIEW); \
876 glMatrixMode(GL_PROJECTION); \
879 if (This->current_viewport == NULL) { \
880 ERR(ddraw, "No current viewport !\n"); \
881 /* Using standard values */ \
887 if (This->current_viewport->use_vp2) { \
888 height = (GLdouble) This->current_viewport->viewport.vp2.dwHeight; \
889 width = (GLdouble) This->current_viewport->viewport.vp2.dwWidth; \
890 minZ = (GLdouble) This->current_viewport->viewport.vp2.dvMinZ; \
891 maxZ = (GLdouble) This->current_viewport->viewport.vp2.dvMaxZ; \
893 height = (GLdouble) This->current_viewport->viewport.vp1.dwHeight; \
894 width = (GLdouble) This->current_viewport->viewport.vp1.dwWidth; \
895 minZ = (GLdouble) This->current_viewport->viewport.vp1.dvMinZ; \
896 maxZ = (GLdouble) This->current_viewport->viewport.vp1.dvMaxZ; \
900 glOrtho(0.0, width, height, 0.0, -minZ, -maxZ); \
904 ERR(ddraw, "Unhandled vertex type\n"); \
912 case D3DPT_POINTLIST: \
913 TRACE(ddraw, "Start POINTS\n"); \
914 glBegin(GL_POINTS); \
917 case D3DPT_LINELIST: \
918 TRACE(ddraw, "Start LINES\n"); \
922 case D3DPT_LINESTRIP: \
923 TRACE(ddraw, "Start LINE_STRIP\n"); \
924 glBegin(GL_LINE_STRIP); \
927 case D3DPT_TRIANGLELIST: \
928 TRACE(ddraw, "Start TRIANGLES\n"); \
929 glBegin(GL_TRIANGLES); \
932 case D3DPT_TRIANGLESTRIP: \
933 TRACE(ddraw, "Start TRIANGLE_STRIP\n"); \
934 glBegin(GL_TRIANGLE_STRIP); \
937 case D3DPT_TRIANGLEFAN: \
938 TRACE(ddraw, "Start TRIANGLE_FAN\n"); \
939 glBegin(GL_TRIANGLE_FAN); \
943 TRACE(ddraw, "Unhandled primitive\n"); \
947 /* Draw the primitives */ \
948 for (vx_index = 0; vx_index < MAXVERT; vx_index++) { \
950 case D3DVT_VERTEX: { \
951 D3DVERTEX *vx = ((D3DVERTEX *) lpvertex) + INDEX; \
953 glNormal3f(vx->nx.nx, vx->ny.ny, vx->nz.nz); \
954 glVertex3f(vx->x.x, vx->y.y, vx->z.z); \
955 TRACE(ddraw, " V: %f %f %f\n", vx->x.x, vx->y.y, vx->z.z); \
958 case D3DVT_LVERTEX: { \
959 D3DLVERTEX *vx = ((D3DLVERTEX *) lpvertex) + INDEX; \
960 DWORD col = vx->c.color; \
962 glColor3f(((col >> 16) & 0xFF) / 255.0, \
963 ((col >> 8) & 0xFF) / 255.0, \
964 ((col >> 0) & 0xFF) / 255.0); \
965 glVertex3f(vx->x.x, vx->y.y, vx->z.z); \
966 TRACE(ddraw, " LV: %f %f %f (%02lx %02lx %02lx)\n", \
967 vx->x.x, vx->y.y, vx->z.z, \
968 ((col >> 16) & 0xFF), ((col >> 8) & 0xFF), ((col >> 0) & 0xFF)); \
971 case D3DVT_TLVERTEX: { \
972 D3DTLVERTEX *vx = ((D3DTLVERTEX *) lpvertex) + INDEX; \
973 DWORD col = vx->c.color; \
975 glColor3f(((col >> 16) & 0xFF) / 255.0, \
976 ((col >> 8) & 0xFF) / 255.0, \
977 ((col >> 0) & 0xFF) / 255.0); \
978 glTexCoord2f(vx->u.tu, vx->v.tv); \
979 if (vx->r.rhw < 0.01) \
980 glVertex3f(vx->x.sx, \
984 glVertex4f(vx->x.sx / vx->r.rhw, \
985 vx->y.sy / vx->r.rhw, \
986 vx->z.sz / vx->r.rhw, \
988 TRACE(ddraw, " TLV: %f %f %f (%02lx %02lx %02lx) (%f %f) (%f)\n", \
989 vx->x.sx, vx->y.sy, vx->z.sz, \
990 ((col >> 16) & 0xFF), ((col >> 8) & 0xFF), ((col >> 0) & 0xFF), \
991 vx->u.tu, vx->v.tv, vx->r.rhw); \
995 TRACE(ddraw, "Unhandled vertex type\n"); \
1001 TRACE(ddraw, "End\n");
1004 static HRESULT WINAPI IDirect3DDevice2Impl_DrawPrimitive(LPDIRECT3DDEVICE2 iface,
1005 D3DPRIMITIVETYPE d3dp,
1011 ICOM_THIS(IDirect3DDevice2Impl,iface);
1012 OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) This;
1015 TRACE(ddraw, "(%p)->(%d,%d,%p,%ld,%08lx): stub\n", This, d3dp, d3dv, lpvertex, vertcount, dwFlags);
1017 DRAW_PRIMITIVE(vertcount, vx_index);
1024 static HRESULT WINAPI IDirect3DDevice2Impl_DrawIndexedPrimitive(LPDIRECT3DDEVICE2 iface,
1025 D3DPRIMITIVETYPE d3dp,
1033 ICOM_THIS(IDirect3DDevice2Impl,iface);
1034 OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) This;
1037 TRACE(ddraw, "(%p)->(%d,%d,%p,%ld,%p,%ld,%08lx): stub\n", This, d3dp, d3dv, lpvertex, vertcount, lpindexes, indexcount, dwFlags);
1039 DRAW_PRIMITIVE(indexcount, lpindexes[vx_index]);
1046 static HRESULT WINAPI IDirect3DDevice2Impl_SetClipStatus(LPDIRECT3DDEVICE2 iface,
1047 LPD3DCLIPSTATUS lpcs)
1049 ICOM_THIS(IDirect3DDevice2Impl,iface);
1050 FIXME(ddraw, "(%p)->(%p): stub\n", This, lpcs);
1057 static HRESULT WINAPI IDirect3DDevice2Impl_GetClipStatus(LPDIRECT3DDEVICE2 iface,
1058 LPD3DCLIPSTATUS lpcs)
1060 ICOM_THIS(IDirect3DDevice2Impl,iface);
1061 FIXME(ddraw, "(%p)->(%p): stub\n", This, lpcs);
1068 /*******************************************************************************
1069 * OpenGL-specific IDirect3DDevice2
1072 /*******************************************************************************
1073 * OpenGL-specific VTable
1076 static ICOM_VTABLE(IDirect3DDevice2) OpenGL_vtable = {
1077 IDirect3DDevice2Impl_QueryInterface,
1078 IDirect3DDevice2Impl_AddRef,
1079 IDirect3DDevice2Impl_Release,
1080 /*** IDirect3DDevice2 methods ***/
1081 IDirect3DDevice2Impl_GetCaps,
1082 IDirect3DDevice2Impl_SwapTextureHandles,
1083 IDirect3DDevice2Impl_GetStats,
1084 IDirect3DDevice2Impl_AddViewport,
1085 IDirect3DDevice2Impl_DeleteViewport,
1086 IDirect3DDevice2Impl_NextViewport,
1087 IDirect3DDevice2Impl_EnumTextureFormats,
1088 IDirect3DDevice2Impl_BeginScene,
1089 IDirect3DDevice2Impl_EndScene,
1090 IDirect3DDevice2Impl_GetDirect3D,
1092 /*** DrawPrimitive API ***/
1093 IDirect3DDevice2Impl_SetCurrentViewport,
1094 IDirect3DDevice2Impl_GetCurrentViewport,
1096 IDirect3DDevice2Impl_SetRenderTarget,
1097 IDirect3DDevice2Impl_GetRenderTarget,
1099 IDirect3DDevice2Impl_Begin,
1100 IDirect3DDevice2Impl_BeginIndexed,
1101 IDirect3DDevice2Impl_Vertex,
1102 IDirect3DDevice2Impl_Index,
1103 IDirect3DDevice2Impl_End,
1105 IDirect3DDevice2Impl_GetRenderState,
1106 IDirect3DDevice2Impl_SetRenderState,
1107 IDirect3DDevice2Impl_GetLightState,
1108 IDirect3DDevice2Impl_SetLightState,
1109 IDirect3DDevice2Impl_SetTransform,
1110 IDirect3DDevice2Impl_GetTransform,
1111 IDirect3DDevice2Impl_MultiplyTransform,
1113 IDirect3DDevice2Impl_DrawPrimitive,
1114 IDirect3DDevice2Impl_DrawIndexedPrimitive,
1116 IDirect3DDevice2Impl_SetClipStatus,
1117 IDirect3DDevice2Impl_GetClipStatus,
1120 /*******************************************************************************
1123 int d3d_OpenGL_dx3(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) {
1124 D3DDEVICEDESC d1,d2;
1126 TRACE(ddraw," Enumerating OpenGL D3D device.\n");
1128 fill_opengl_caps(&d1, &d2);
1130 return cb((void*)&IID_D3DDEVICE_OpenGL,"WINE Direct3D using OpenGL","direct3d",&d1,&d2,context);
1133 float id_mat[16] = {
1140 int is_OpenGL_dx3(REFCLSID rguid, IDirectDrawSurfaceImpl* surface, IDirect3DDeviceImpl** device)
1142 if (!memcmp(&IID_D3DDEVICE_OpenGL,rguid,sizeof(IID_D3DDEVICE_OpenGL))) {
1143 OpenGL_IDirect3DDevice *odev;
1145 *device = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(OpenGL_IDirect3DDevice));
1146 odev = (OpenGL_IDirect3DDevice *) (*device);
1148 (*device)->lpvtbl = &OpenGL_vtable_dx3;
1149 (*device)->d3d = NULL;
1150 (*device)->surface = surface;
1152 (*device)->viewport_list = NULL;
1153 (*device)->current_viewport = NULL;
1155 (*device)->set_context = set_context_dx3;
1157 TRACE(ddraw, "OpenGL device created \n");
1159 /* Create the OpenGL context */
1160 odev->ctx = OSMesaCreateContext(OSMESA_RGBA, NULL);
1161 odev->buffer = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
1162 surface->s.surface_desc.dwWidth * surface->s.surface_desc.dwHeight * 4);
1163 odev->rs.src = GL_ONE;
1164 odev->rs.dst = GL_ZERO;
1165 odev->rs.mag = GL_NEAREST;
1166 odev->rs.min = GL_NEAREST;
1168 odev->world_mat = (LPD3DMATRIX) &id_mat;
1169 odev->view_mat = (LPD3DMATRIX) &id_mat;
1170 odev->proj_mat = (LPD3DMATRIX) &id_mat;
1172 /* Initialisation */
1173 (*device)->set_context(*device);
1174 glClearColor(0.0, 0.0, 0.0, 0.0);
1175 glColor3f(1.0, 1.0, 1.0);
1180 /* This is not the OpenGL UID */
1185 /*******************************************************************************
1188 static HRESULT WINAPI IDirect3DDeviceImpl_QueryInterface(LPDIRECT3DDEVICE iface,
1192 ICOM_THIS(IDirect3DDeviceImpl,iface);
1195 WINE_StringFromCLSID((LPCLSID)riid,xrefiid);
1196 FIXME(ddraw, "(%p)->(%s,%p): stub\n", This, xrefiid,ppvObj);
1203 static ULONG WINAPI IDirect3DDeviceImpl_AddRef(LPDIRECT3DDEVICE iface)
1205 ICOM_THIS(IDirect3DDeviceImpl,iface);
1206 TRACE(ddraw, "(%p)->()incrementing from %lu.\n", This, This->ref );
1208 return ++(This->ref);
1213 static ULONG WINAPI IDirect3DDeviceImpl_Release(LPDIRECT3DDEVICE iface)
1215 ICOM_THIS(IDirect3DDeviceImpl,iface);
1216 FIXME( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
1218 if (!--(This->ref)) {
1219 HeapFree(GetProcessHeap(),0,This);
1226 static HRESULT WINAPI IDirect3DDeviceImpl_Initialize(LPDIRECT3DDEVICE iface,
1229 LPD3DDEVICEDESC lpd3ddvdesc)
1231 ICOM_THIS(IDirect3DDeviceImpl,iface);
1232 TRACE(ddraw, "(%p)->(%p,%p,%p): stub\n", This, lpd3d,lpGUID, lpd3ddvdesc);
1234 return DDERR_ALREADYINITIALIZED;
1238 static HRESULT WINAPI IDirect3DDeviceImpl_GetCaps(LPDIRECT3DDEVICE iface,
1239 LPD3DDEVICEDESC lpD3DHWDevDesc,
1240 LPD3DDEVICEDESC lpD3DSWDevDesc)
1242 ICOM_THIS(IDirect3DDeviceImpl,iface);
1243 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpD3DHWDevDesc, lpD3DSWDevDesc);
1245 fill_opengl_caps(lpD3DHWDevDesc, lpD3DSWDevDesc);
1251 static HRESULT WINAPI IDirect3DDeviceImpl_SwapTextureHandles(LPDIRECT3DDEVICE iface,
1252 LPDIRECT3DTEXTURE lpD3DTex1,
1253 LPDIRECT3DTEXTURE lpD3DTex2)
1255 ICOM_THIS(IDirect3DDeviceImpl,iface);
1256 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpD3DTex1, lpD3DTex2);
1261 static HRESULT WINAPI IDirect3DDeviceImpl_CreateExecuteBuffer(LPDIRECT3DDEVICE iface,
1262 LPD3DEXECUTEBUFFERDESC lpDesc,
1263 LPDIRECT3DEXECUTEBUFFER *lplpDirect3DExecuteBuffer,
1264 IUnknown *pUnkOuter)
1266 ICOM_THIS(IDirect3DDeviceImpl,iface);
1267 TRACE(ddraw, "(%p)->(%p,%p,%p)\n", This, lpDesc, lplpDirect3DExecuteBuffer, pUnkOuter);
1269 *lplpDirect3DExecuteBuffer = d3dexecutebuffer_create(This, lpDesc);
1275 static HRESULT WINAPI IDirect3DDeviceImpl_GetStats(LPDIRECT3DDEVICE iface,
1276 LPD3DSTATS lpD3DStats)
1278 ICOM_THIS(IDirect3DDeviceImpl,iface);
1279 TRACE(ddraw, "(%p)->(%p): stub\n", This, lpD3DStats);
1285 static HRESULT WINAPI IDirect3DDeviceImpl_Execute(LPDIRECT3DDEVICE iface,
1286 LPDIRECT3DEXECUTEBUFFER lpDirect3DExecuteBuffer,
1287 LPDIRECT3DVIEWPORT lpDirect3DViewport,
1290 ICOM_THIS(IDirect3DDeviceImpl,iface);
1291 TRACE(ddraw, "(%p)->(%p,%p,%08ld): stub\n", This, lpDirect3DExecuteBuffer, lpDirect3DViewport, dwFlags);
1293 /* Put this as the default context */
1296 ((IDirect3DExecuteBufferImpl*)lpDirect3DExecuteBuffer)->execute(lpDirect3DExecuteBuffer, iface, lpDirect3DViewport);
1301 static HRESULT WINAPI IDirect3DDeviceImpl_AddViewport(LPDIRECT3DDEVICE iface,
1302 LPDIRECT3DVIEWPORT lpvp)
1304 ICOM_THIS(IDirect3DDeviceImpl,iface);
1305 IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
1306 FIXME(ddraw, "(%p)->(%p): stub\n", This, ilpvp);
1308 /* Adds this viewport to the viewport list */
1309 ilpvp->next = This->viewport_list;
1310 This->viewport_list = ilpvp;
1317 static HRESULT WINAPI IDirect3DDeviceImpl_DeleteViewport(LPDIRECT3DDEVICE iface,
1318 LPDIRECT3DVIEWPORT lpvp)
1320 ICOM_THIS(IDirect3DDeviceImpl,iface);
1321 IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
1322 IDirect3DViewport2Impl *cur, *prev;
1323 FIXME(ddraw, "(%p)->(%p): stub\n", This, lpvp);
1325 /* Finds this viewport in the list */
1327 cur = This->viewport_list;
1328 while ((cur != NULL) && (cur != ilpvp)) {
1333 return DDERR_INVALIDOBJECT;
1337 This->viewport_list = cur->next;
1339 prev->next = cur->next;
1346 static HRESULT WINAPI IDirect3DDeviceImpl_NextViewport(LPDIRECT3DDEVICE iface,
1347 LPDIRECT3DVIEWPORT lpvp,
1348 LPDIRECT3DVIEWPORT* lplpvp,
1351 ICOM_THIS(IDirect3DDeviceImpl,iface);
1352 IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
1353 IDirect3DViewport2Impl** ilplpvp=(IDirect3DViewport2Impl**)lplpvp;
1354 FIXME(ddraw, "(%p)->(%p,%p,%08lx): stub\n", This, ilpvp, ilplpvp, dwFlags);
1358 *ilplpvp = ilpvp->next;
1362 *ilplpvp = This->viewport_list;
1366 ilpvp = This->viewport_list;
1367 while (ilpvp->next != NULL)
1368 ilpvp = ilpvp->next;
1374 return DDERR_INVALIDPARAMS;
1380 static HRESULT WINAPI IDirect3DDeviceImpl_Pick(LPDIRECT3DDEVICE iface,
1381 LPDIRECT3DEXECUTEBUFFER lpDirect3DExecuteBuffer,
1382 LPDIRECT3DVIEWPORT lpDirect3DViewport,
1386 ICOM_THIS(IDirect3DDeviceImpl,iface);
1387 TRACE(ddraw, "(%p)->(%p,%p,%08lx,%p): stub\n", This, lpDirect3DExecuteBuffer, lpDirect3DViewport,
1394 static HRESULT WINAPI IDirect3DDeviceImpl_GetPickRecords(LPDIRECT3DDEVICE iface,
1396 LPD3DPICKRECORD lpD3DPickRec)
1398 ICOM_THIS(IDirect3DDeviceImpl,iface);
1399 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpCount, lpD3DPickRec);
1405 static HRESULT WINAPI IDirect3DDeviceImpl_EnumTextureFormats(LPDIRECT3DDEVICE iface,
1406 LPD3DENUMTEXTUREFORMATSCALLBACK lpd3dEnumTextureProc,
1409 ICOM_THIS(IDirect3DDeviceImpl,iface);
1410 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpd3dEnumTextureProc, lpArg);
1412 return enum_texture_format_OpenGL(lpd3dEnumTextureProc, lpArg);
1416 static HRESULT WINAPI IDirect3DDeviceImpl_CreateMatrix(LPDIRECT3DDEVICE iface,
1417 LPD3DMATRIXHANDLE lpD3DMatHandle)
1419 ICOM_THIS(IDirect3DDeviceImpl,iface);
1420 TRACE(ddraw, "(%p)->(%p)\n", This, lpD3DMatHandle);
1422 *lpD3DMatHandle = (D3DMATRIXHANDLE) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(D3DMATRIX));
1428 static HRESULT WINAPI IDirect3DDeviceImpl_SetMatrix(LPDIRECT3DDEVICE iface,
1429 D3DMATRIXHANDLE d3dMatHandle,
1430 const LPD3DMATRIX lpD3DMatrix)
1432 ICOM_THIS(IDirect3DDeviceImpl,iface);
1433 TRACE(ddraw, "(%p)->(%08lx,%p)\n", This, d3dMatHandle, lpD3DMatrix);
1435 dump_mat(lpD3DMatrix);
1437 *((D3DMATRIX *) d3dMatHandle) = *lpD3DMatrix;
1443 static HRESULT WINAPI IDirect3DDeviceImpl_GetMatrix(LPDIRECT3DDEVICE iface,
1444 D3DMATRIXHANDLE D3DMatHandle,
1445 LPD3DMATRIX lpD3DMatrix)
1447 ICOM_THIS(IDirect3DDeviceImpl,iface);
1448 TRACE(ddraw, "(%p)->(%08lx,%p)\n", This, D3DMatHandle, lpD3DMatrix);
1450 *lpD3DMatrix = *((D3DMATRIX *) D3DMatHandle);
1456 static HRESULT WINAPI IDirect3DDeviceImpl_DeleteMatrix(LPDIRECT3DDEVICE iface,
1457 D3DMATRIXHANDLE d3dMatHandle)
1459 ICOM_THIS(IDirect3DDeviceImpl,iface);
1460 TRACE(ddraw, "(%p)->(%08lx)\n", This, d3dMatHandle);
1462 HeapFree(GetProcessHeap(),0, (void *) d3dMatHandle);
1468 static HRESULT WINAPI IDirect3DDeviceImpl_BeginScene(LPDIRECT3DDEVICE iface)
1470 ICOM_THIS(IDirect3DDeviceImpl,iface);
1471 /* OpenGL_IDirect3DDevice *odev = (OpenGL_IDirect3DDevice *) This; */
1473 FIXME(ddraw, "(%p)->(): stub\n", This);
1475 /* We get the pointer to the surface (should be done on flip) */
1476 /* odev->zb->pbuf = This->surface->s.surface_desc.y.lpSurface; */
1482 /* This is for the moment copy-pasted from IDirect3DDevice2...
1483 Will make a common function ... */
1484 static HRESULT WINAPI IDirect3DDeviceImpl_EndScene(LPDIRECT3DDEVICE iface)
1486 ICOM_THIS(IDirect3DDeviceImpl,iface);
1487 OpenGL_IDirect3DDevice *odev = (OpenGL_IDirect3DDevice *) This;
1488 LPDIRECTDRAWSURFACE3 surf = (LPDIRECTDRAWSURFACE3) This->surface;
1489 DDSURFACEDESC sdesc;
1492 unsigned short *dest;
1494 FIXME(ddraw, "(%p)->(): stub\n", This);
1496 /* Here we copy back the OpenGL scene to the the DDraw surface */
1497 /* First, lock the surface */
1498 IDirectDrawSurface3_Lock(surf,NULL,&sdesc,DDLOCK_WRITEONLY,0);
1500 /* The copy the OpenGL buffer to this surface */
1502 /* NOTE : this is only for debugging purpose. I KNOW it is really unoptimal.
1503 I am currently working on a set of patches for Mesa to have OSMesa support
1504 16 bpp surfaces => we will able to render directly onto the surface, no
1505 need to do a bpp conversion */
1506 dest = (unsigned short *) sdesc.y.lpSurface;
1507 src = ((unsigned char *) odev->buffer) + 4 * (sdesc.dwWidth * (sdesc.dwHeight - 1));
1508 for (y = 0; y < sdesc.dwHeight; y++) {
1509 unsigned char *lsrc = src;
1511 for (x = 0; x < sdesc.dwWidth ; x++) {
1512 unsigned char r = *lsrc++;
1513 unsigned char g = *lsrc++;
1514 unsigned char b = *lsrc++;
1517 *dest = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
1522 src -= 4 * sdesc.dwWidth;
1525 /* Unlock the surface */
1526 IDirectDrawSurface3_Unlock(surf,sdesc.y.lpSurface);
1532 static HRESULT WINAPI IDirect3DDeviceImpl_GetDirect3D(LPDIRECT3DDEVICE iface,
1533 LPDIRECT3D *lpDirect3D)
1535 ICOM_THIS(IDirect3DDeviceImpl,iface);
1536 TRACE(ddraw, "(%p)->(%p): stub\n", This, lpDirect3D);
1543 /*******************************************************************************
1544 * Direct3DDevice VTable
1546 static ICOM_VTABLE(IDirect3DDevice) OpenGL_vtable_dx3 = {
1547 IDirect3DDeviceImpl_QueryInterface,
1548 IDirect3DDeviceImpl_AddRef,
1549 IDirect3DDeviceImpl_Release,
1550 IDirect3DDeviceImpl_Initialize,
1551 IDirect3DDeviceImpl_GetCaps,
1552 IDirect3DDeviceImpl_SwapTextureHandles,
1553 IDirect3DDeviceImpl_CreateExecuteBuffer,
1554 IDirect3DDeviceImpl_GetStats,
1555 IDirect3DDeviceImpl_Execute,
1556 IDirect3DDeviceImpl_AddViewport,
1557 IDirect3DDeviceImpl_DeleteViewport,
1558 IDirect3DDeviceImpl_NextViewport,
1559 IDirect3DDeviceImpl_Pick,
1560 IDirect3DDeviceImpl_GetPickRecords,
1561 IDirect3DDeviceImpl_EnumTextureFormats,
1562 IDirect3DDeviceImpl_CreateMatrix,
1563 IDirect3DDeviceImpl_SetMatrix,
1564 IDirect3DDeviceImpl_GetMatrix,
1565 IDirect3DDeviceImpl_DeleteMatrix,
1566 IDirect3DDeviceImpl_BeginScene,
1567 IDirect3DDeviceImpl_EndScene,
1568 IDirect3DDeviceImpl_GetDirect3D,
1571 #else /* HAVE_MESAGL */
1573 int d3d_OpenGL(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) {
1577 int is_OpenGL(REFCLSID rguid, IDirectDrawSurfaceImpl* surface, IDirect3DDevice2Impl** device, IDirect3D2Impl* d3d)
1582 int d3d_OpenGL_dx3(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) {
1586 int is_OpenGL_dx3(REFCLSID rguid, IDirectDrawSurfaceImpl* surface, IDirect3DDeviceImpl** device)
1591 #endif /* HAVE_MESAGL */