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"
15 #include "debugtools.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.1b2 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;
54 OSMesaMakeCurrent(odev->ctx, odev->buffer,
56 This->surface->s.surface_desc.dwWidth,
57 This->surface->s.surface_desc.dwHeight);
59 if (glXMakeCurrent(display,
60 odev->common.surface->s.ddraw->d.drawable,
61 odev->ctx) == False) {
62 ERR("Error in setting current context (context %p drawable %ld)!\n",
63 odev->ctx, odev->common.surface->s.ddraw->d.drawable);
68 static void set_context_dx3(IDirect3DDeviceImpl* This) {
69 OpenGL_IDirect3DDevice *odev = (OpenGL_IDirect3DDevice *) This;
72 OSMesaMakeCurrent(odev->ctx, odev->buffer,
74 This->surface->s.surface_desc.dwWidth,
75 This->surface->s.surface_desc.dwHeight);
77 if (glXMakeCurrent(display,
78 odev->common.surface->s.ddraw->d.drawable,
79 odev->ctx) == False) {
80 ERR("Error in setting current context !\n");
85 static void fill_opengl_primcaps(D3DPRIMCAPS *pc)
87 pc->dwSize = sizeof(*pc);
88 pc->dwMiscCaps = D3DPMISCCAPS_CONFORMANT | D3DPMISCCAPS_CULLCCW | D3DPMISCCAPS_CULLCW |
89 D3DPMISCCAPS_LINEPATTERNREP | D3DPMISCCAPS_MASKZ;
90 pc->dwRasterCaps = D3DPRASTERCAPS_DITHER | D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_FOGTABLE |
91 D3DPRASTERCAPS_FOGVERTEX | D3DPRASTERCAPS_STIPPLE | D3DPRASTERCAPS_ZBIAS | D3DPRASTERCAPS_ZTEST;
92 pc->dwZCmpCaps = 0xFFFFFFFF; /* All Z test can be done */
93 pc->dwSrcBlendCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
94 pc->dwDestBlendCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
95 pc->dwAlphaCmpCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
96 pc->dwShadeCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
97 pc->dwTextureCaps = D3DPTEXTURECAPS_ALPHA | D3DPTEXTURECAPS_BORDER | D3DPTEXTURECAPS_PERSPECTIVE |
98 D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_TRANSPARENCY;
99 pc->dwTextureFilterCaps = D3DPTFILTERCAPS_LINEAR | D3DPTFILTERCAPS_LINEARMIPLINEAR | D3DPTFILTERCAPS_LINEARMIPNEAREST |
100 D3DPTFILTERCAPS_MIPLINEAR | D3DPTFILTERCAPS_MIPNEAREST | D3DPTFILTERCAPS_NEAREST;
101 pc->dwTextureBlendCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
102 pc->dwTextureAddressCaps = D3DPTADDRESSCAPS_BORDER | D3DPTADDRESSCAPS_CLAMP | D3DPTADDRESSCAPS_WRAP;
103 pc->dwStippleWidth = 32;
104 pc->dwStippleHeight = 32;
107 static void fill_opengl_caps(D3DDEVICEDESC *d1, D3DDEVICEDESC *d2)
109 /* GLint maxlight; */
111 d1->dwSize = sizeof(*d1);
112 d1->dwFlags = D3DDD_DEVCAPS | D3DDD_BCLIPPING | D3DDD_COLORMODEL | D3DDD_DEVICERENDERBITDEPTH | D3DDD_DEVICEZBUFFERBITDEPTH
113 | D3DDD_LIGHTINGCAPS | D3DDD_LINECAPS | D3DDD_MAXBUFFERSIZE | D3DDD_MAXVERTEXCOUNT | D3DDD_TRANSFORMCAPS | D3DDD_TRICAPS;
114 d1->dcmColorModel = D3DCOLOR_RGB;
115 d1->dwDevCaps = D3DDEVCAPS_CANRENDERAFTERFLIP | D3DDEVCAPS_DRAWPRIMTLVERTEX | D3DDEVCAPS_EXECUTESYSTEMMEMORY |
116 D3DDEVCAPS_EXECUTEVIDEOMEMORY | D3DDEVCAPS_FLOATTLVERTEX | D3DDEVCAPS_TEXTURENONLOCALVIDMEM | D3DDEVCAPS_TEXTURESYSTEMMEMORY |
117 D3DDEVCAPS_TEXTUREVIDEOMEMORY | D3DDEVCAPS_TLVERTEXSYSTEMMEMORY | D3DDEVCAPS_TLVERTEXVIDEOMEMORY;
118 d1->dtcTransformCaps.dwSize = sizeof(D3DTRANSFORMCAPS);
119 d1->dtcTransformCaps.dwCaps = D3DTRANSFORMCAPS_CLIP;
120 d1->bClipping = TRUE;
121 d1->dlcLightingCaps.dwSize = sizeof(D3DLIGHTINGCAPS);
122 d1->dlcLightingCaps.dwCaps = D3DLIGHTCAPS_DIRECTIONAL | D3DLIGHTCAPS_PARALLELPOINT | D3DLIGHTCAPS_POINT | D3DLIGHTCAPS_SPOT;
123 d1->dlcLightingCaps.dwLightingModel = D3DLIGHTINGMODEL_RGB;
124 d1->dlcLightingCaps.dwNumLights = 16; /* glGetIntegerv(GL_MAX_LIGHTS, &maxlight); d1->dlcLightingCaps.dwNumLights = maxlight; */
125 fill_opengl_primcaps(&(d1->dpcLineCaps));
126 fill_opengl_primcaps(&(d1->dpcTriCaps));
127 d1->dwDeviceRenderBitDepth = DDBD_16;
128 d1->dwDeviceZBufferBitDepth = DDBD_16;
129 d1->dwMaxBufferSize = 0;
130 d1->dwMaxVertexCount = 65536;
131 d1->dwMinTextureWidth = 1;
132 d1->dwMinTextureHeight = 1;
133 d1->dwMaxTextureWidth = 256; /* This is for Mesa on top of Glide (in the future :-) ) */
134 d1->dwMaxTextureHeight = 256; /* This is for Mesa on top of Glide (in the future :-) ) */
135 d1->dwMinStippleWidth = 1;
136 d1->dwMinStippleHeight = 1;
137 d1->dwMaxStippleWidth = 32;
138 d1->dwMaxStippleHeight = 32;
140 d2->dwSize = sizeof(*d2);
144 int d3d_OpenGL(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) {
147 TRACE(" Enumerating OpenGL D3D device.\n");
149 fill_opengl_caps(&d1, &d2);
151 return cb((void*)&IID_D3DDEVICE2_OpenGL,"WINE Direct3D using OpenGL","direct3d",&d1,&d2,context);
154 int is_OpenGL(REFCLSID rguid, IDirectDrawSurfaceImpl* surface, IDirect3DDevice2Impl** device, IDirect3D2Impl* d3d)
156 if (/* Default device */
159 (!memcmp(&IID_IDirect3DHALDevice,rguid,sizeof(IID_IDirect3DHALDevice))) ||
161 (!memcmp(&IID_D3DDEVICE2_OpenGL,rguid,sizeof(IID_D3DDEVICE2_OpenGL)))) {
162 OpenGL_IDirect3DDevice2 *odev;
164 const float id_mat[16] = {
171 int attributeList[]={ GLX_RGBA, GLX_DEPTH_SIZE, 16, GLX_DOUBLEBUFFER, None };
175 *device = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(OpenGL_IDirect3DDevice2));
176 odev = (OpenGL_IDirect3DDevice2 *) (*device);
178 (*device)->lpvtbl = &OpenGL_vtable;
179 (*device)->d3d = d3d;
180 (*device)->surface = surface;
182 (*device)->viewport_list = NULL;
183 (*device)->current_viewport = NULL;
185 (*device)->set_context = set_context;
187 TRACE("Creating OpenGL device for surface %p\n", surface);
189 /* Create the OpenGL context */
191 odev->ctx = OSMesaCreateContext(OSMESA_RGBA, NULL);
192 odev->buffer = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
193 surface->s.surface_desc.dwWidth * surface->s.surface_desc.dwHeight * 4);
195 /* First get the correct visual */
196 TRACE("Backbuffer : %d\n", surface->s.backbuffer == NULL);
197 /* if (surface->s.backbuffer == NULL)
198 attributeList[3] = None; */
200 xvis = glXChooseVisual(display,
201 DefaultScreen(display),
204 ERR("No visual found !\n");
206 TRACE("Visual found\n");
207 /* Create the context */
208 odev->ctx = glXCreateContext(display,
212 if (odev->ctx == NULL)
213 ERR("Error in context creation !\n");
215 TRACE("Context created (%p)\n", odev->ctx);
217 /* Now override the surface's Flip method (if in double buffering) */
218 surface->s.d3d_device = (void *) odev;
219 if (surface->s.backbuffer != NULL)
220 surface->s.backbuffer->s.d3d_device = (void *) odev;
222 odev->rs.src = GL_ONE;
223 odev->rs.dst = GL_ZERO;
224 odev->rs.mag = GL_NEAREST;
225 odev->rs.min = GL_NEAREST;
228 memcpy(odev->world_mat, id_mat, 16 * sizeof(float));
229 memcpy(odev->view_mat , id_mat, 16 * sizeof(float));
230 memcpy(odev->proj_mat , id_mat, 16 * sizeof(float));
233 TRACE("Setting current context\n");
234 (*device)->set_context(*device);
235 TRACE("Current context set\n");
236 glClearColor(0.0, 0.0, 0.0, 0.0);
237 glColor3f(1.0, 1.0, 1.0);
240 TRACE("OpenGL device created \n");
245 /* This is not the OpenGL UID */
249 /*******************************************************************************
250 * Common IDirect3DDevice2
253 static HRESULT WINAPI IDirect3DDevice2Impl_QueryInterface(LPDIRECT3DDEVICE2 iface,
257 ICOM_THIS(IDirect3DDevice2Impl,iface);
260 WINE_StringFromCLSID((LPCLSID)riid,xrefiid);
261 FIXME("(%p)->(%s,%p): stub\n", This, xrefiid,ppvObj);
268 static ULONG WINAPI IDirect3DDevice2Impl_AddRef(LPDIRECT3DDEVICE2 iface)
270 ICOM_THIS(IDirect3DDevice2Impl,iface);
271 TRACE("(%p)->()incrementing from %lu.\n", This, This->ref );
273 return ++(This->ref);
278 static ULONG WINAPI IDirect3DDevice2Impl_Release(LPDIRECT3DDEVICE2 iface)
280 ICOM_THIS(IDirect3DDevice2Impl,iface);
281 FIXME("(%p)->() decrementing from %lu.\n", This, This->ref );
283 if (!--(This->ref)) {
284 OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) This;
287 OSMesaDestroyContext(odev->ctx);
290 glXDestroyContext(display,
295 HeapFree(GetProcessHeap(),0,This);
303 /*** IDirect3DDevice2 methods ***/
304 static HRESULT WINAPI IDirect3DDevice2Impl_GetCaps(LPDIRECT3DDEVICE2 iface,
305 LPD3DDEVICEDESC lpdescsoft,
306 LPD3DDEVICEDESC lpdeschard)
308 ICOM_THIS(IDirect3DDevice2Impl,iface);
309 FIXME("(%p)->(%p,%p): stub\n", This, lpdescsoft, lpdeschard);
311 fill_opengl_caps(lpdescsoft, lpdeschard);
318 static HRESULT WINAPI IDirect3DDevice2Impl_SwapTextureHandles(LPDIRECT3DDEVICE2 iface,
319 LPDIRECT3DTEXTURE2 lptex1,
320 LPDIRECT3DTEXTURE2 lptex2)
322 ICOM_THIS(IDirect3DDevice2Impl,iface);
323 FIXME("(%p)->(%p,%p): stub\n", This, lptex1, lptex2);
330 static HRESULT WINAPI IDirect3DDevice2Impl_GetStats(LPDIRECT3DDEVICE2 iface,
333 ICOM_THIS(IDirect3DDevice2Impl,iface);
334 FIXME("(%p)->(%p): stub\n", This, lpstats);
341 static HRESULT WINAPI IDirect3DDevice2Impl_AddViewport(LPDIRECT3DDEVICE2 iface,
342 LPDIRECT3DVIEWPORT2 lpvp)
344 ICOM_THIS(IDirect3DDevice2Impl,iface);
345 IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
346 FIXME("(%p)->(%p): stub\n", This, ilpvp);
348 /* Adds this viewport to the viewport list */
349 ilpvp->next = This->viewport_list;
350 This->viewport_list = ilpvp;
357 static HRESULT WINAPI IDirect3DDevice2Impl_DeleteViewport(LPDIRECT3DDEVICE2 iface,
358 LPDIRECT3DVIEWPORT2 lpvp)
360 ICOM_THIS(IDirect3DDevice2Impl,iface);
361 IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
362 IDirect3DViewport2Impl *cur, *prev;
363 FIXME("(%p)->(%p): stub\n", This, lpvp);
365 /* Finds this viewport in the list */
367 cur = This->viewport_list;
368 while ((cur != NULL) && (cur != ilpvp)) {
373 return DDERR_INVALIDOBJECT;
377 This->viewport_list = cur->next;
379 prev->next = cur->next;
386 static HRESULT WINAPI IDirect3DDevice2Impl_NextViewport(LPDIRECT3DDEVICE2 iface,
387 LPDIRECT3DVIEWPORT2 lpvp,
388 LPDIRECT3DVIEWPORT2* lplpvp,
391 ICOM_THIS(IDirect3DDevice2Impl,iface);
392 IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
393 IDirect3DViewport2Impl** ilplpvp=(IDirect3DViewport2Impl**)lplpvp;
394 FIXME("(%p)->(%p,%p,%08lx): stub\n", This, lpvp, lpvp, dwFlags);
398 *ilplpvp = ilpvp->next;
402 *ilplpvp = This->viewport_list;
406 ilpvp = This->viewport_list;
407 while (ilpvp->next != NULL)
414 return DDERR_INVALIDPARAMS;
420 static HRESULT enum_texture_format_OpenGL(LPD3DENUMTEXTUREFORMATSCALLBACK cb,
423 LPDDPIXELFORMAT pformat;
425 /* Do the texture enumeration */
426 sdesc.dwSize = sizeof(DDSURFACEDESC);
427 sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
428 sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
429 pformat = &(sdesc.ddpfPixelFormat);
430 pformat->dwSize = sizeof(DDPIXELFORMAT);
431 pformat->dwFourCC = 0;
433 TRACE("Enumerating GL_RGBA unpacked (32)\n");
434 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
435 pformat->x.dwRGBBitCount = 32;
436 pformat->y.dwRBitMask = 0xFF000000;
437 pformat->z.dwGBitMask = 0x00FF0000;
438 pformat->xx.dwBBitMask = 0x0000FF00;
439 pformat->xy.dwRGBAlphaBitMask = 0x000000FF;
440 if (cb(&sdesc, context) == 0)
443 TRACE("Enumerating GL_RGB unpacked (24)\n");
444 pformat->dwFlags = DDPF_RGB;
445 pformat->x.dwRGBBitCount = 24;
446 pformat->y.dwRBitMask = 0x00FF0000;
447 pformat->z.dwGBitMask = 0x0000FF00;
448 pformat->xx.dwBBitMask = 0x000000FF;
449 pformat->xy.dwRGBAlphaBitMask = 0x00000000;
450 if (cb(&sdesc, context) == 0)
453 #ifndef HAVE_BUGGY_MESAGL
454 /* The packed texture format are buggy in Mesa. The bug was reported and corrected,
455 so that future version will work great. */
456 TRACE("Enumerating GL_RGB packed GL_UNSIGNED_SHORT_5_6_5 (16)\n");
457 pformat->dwFlags = DDPF_RGB;
458 pformat->x.dwRGBBitCount = 16;
459 pformat->y.dwRBitMask = 0x0000F800;
460 pformat->z.dwGBitMask = 0x000007E0;
461 pformat->xx.dwBBitMask = 0x0000001F;
462 pformat->xy.dwRGBAlphaBitMask = 0x00000000;
463 if (cb(&sdesc, context) == 0)
466 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_5_5_5_1 (16)\n");
467 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
468 pformat->x.dwRGBBitCount = 16;
469 pformat->y.dwRBitMask = 0x0000F800;
470 pformat->z.dwGBitMask = 0x000007C0;
471 pformat->xx.dwBBitMask = 0x0000003E;
472 pformat->xy.dwRGBAlphaBitMask = 0x00000001;
473 if (cb(&sdesc, context) == 0)
476 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_4_4_4_4 (16)\n");
477 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
478 pformat->x.dwRGBBitCount = 16;
479 pformat->y.dwRBitMask = 0x0000F000;
480 pformat->z.dwGBitMask = 0x00000F00;
481 pformat->xx.dwBBitMask = 0x000000F0;
482 pformat->xy.dwRGBAlphaBitMask = 0x0000000F;
483 if (cb(&sdesc, context) == 0)
486 TRACE("Enumerating GL_RGB packed GL_UNSIGNED_BYTE_3_3_2 (8)\n");
487 pformat->dwFlags = DDPF_RGB;
488 pformat->x.dwRGBBitCount = 8;
489 pformat->y.dwRBitMask = 0x0000F800;
490 pformat->z.dwGBitMask = 0x000007C0;
491 pformat->xx.dwBBitMask = 0x0000003E;
492 pformat->xy.dwRGBAlphaBitMask = 0x00000001;
493 if (cb(&sdesc, context) == 0)
497 TRACE("Enumerating Paletted (8)\n");
498 pformat->dwFlags = DDPF_PALETTEINDEXED8;
499 pformat->x.dwRGBBitCount = 8;
500 pformat->y.dwRBitMask = 0x00000000;
501 pformat->z.dwGBitMask = 0x00000000;
502 pformat->xx.dwBBitMask = 0x00000000;
503 pformat->xy.dwRGBAlphaBitMask = 0x00000000;
504 if (cb(&sdesc, context) == 0)
507 TRACE("End of enumeration\n");
512 static HRESULT WINAPI IDirect3DDevice2Impl_EnumTextureFormats(LPDIRECT3DDEVICE2 iface,
513 LPD3DENUMTEXTUREFORMATSCALLBACK cb,
516 ICOM_THIS(IDirect3DDevice2Impl,iface);
517 FIXME("(%p)->(%p,%p): stub\n", This, cb, context);
519 return enum_texture_format_OpenGL(cb, context);
524 static HRESULT WINAPI IDirect3DDevice2Impl_BeginScene(LPDIRECT3DDEVICE2 iface)
526 ICOM_THIS(IDirect3DDevice2Impl,iface);
527 /* OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) This; */
529 FIXME("(%p)->(): stub\n", This);
531 /* Here, we should get the DDraw surface and 'copy it' to the
532 OpenGL surface.... */
539 static HRESULT WINAPI IDirect3DDevice2Impl_EndScene(LPDIRECT3DDEVICE2 iface)
541 ICOM_THIS(IDirect3DDevice2Impl,iface);
543 OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) This;
544 LPDIRECTDRAWSURFACE3 surf = (LPDIRECTDRAWSURFACE3) This->surface;
548 unsigned short *dest;
551 FIXME("(%p)->(): stub\n", This);
554 /* Here we copy back the OpenGL scene to the the DDraw surface */
555 /* First, lock the surface */
556 IDirectDrawSurface3_Lock(surf,NULL,&sdesc,DDLOCK_WRITEONLY,0);
558 /* The copy the OpenGL buffer to this surface */
560 /* NOTE : this is only for debugging purpose. I KNOW it is really unoptimal.
561 I am currently working on a set of patches for Mesa to have OSMesa support
562 16 bpp surfaces => we will able to render directly onto the surface, no
563 need to do a bpp conversion */
564 dest = (unsigned short *) sdesc.y.lpSurface;
565 src = ((unsigned char *) odev->buffer) + 4 * (sdesc.dwWidth * (sdesc.dwHeight - 1));
566 for (y = 0; y < sdesc.dwHeight; y++) {
567 unsigned char *lsrc = src;
569 for (x = 0; x < sdesc.dwWidth ; x++) {
570 unsigned char r = *lsrc++;
571 unsigned char g = *lsrc++;
572 unsigned char b = *lsrc++;
574 *dest = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
579 src -= 4 * sdesc.dwWidth;
582 /* Unlock the surface */
583 IDirectDrawSurface3_Unlock(surf,sdesc.y.lpSurface);
585 /* No need to do anything here... */
593 static HRESULT WINAPI IDirect3DDevice2Impl_GetDirect3D(LPDIRECT3DDEVICE2 iface, LPDIRECT3D2 *lpd3d2)
595 ICOM_THIS(IDirect3DDevice2Impl,iface);
596 TRACE("(%p)->(%p): stub\n", This, lpd3d2);
598 *lpd3d2 = (LPDIRECT3D2)This->d3d;
605 /*** DrawPrimitive API ***/
606 static HRESULT WINAPI IDirect3DDevice2Impl_SetCurrentViewport(LPDIRECT3DDEVICE2 iface,
607 LPDIRECT3DVIEWPORT2 lpvp)
609 ICOM_THIS(IDirect3DDevice2Impl,iface);
610 IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
611 FIXME("(%p)->(%p): stub\n", This, ilpvp);
613 /* Should check if the viewport was added or not */
615 /* Set this viewport as the current viewport */
616 This->current_viewport = ilpvp;
618 /* Activate this viewport */
619 ilpvp->device.active_device2 = This;
620 ilpvp->activate(ilpvp);
627 static HRESULT WINAPI IDirect3DDevice2Impl_GetCurrentViewport(LPDIRECT3DDEVICE2 iface,
628 LPDIRECT3DVIEWPORT2 *lplpvp)
630 ICOM_THIS(IDirect3DDevice2Impl,iface);
631 FIXME("(%p)->(%p): stub\n", This, lplpvp);
633 /* Returns the current viewport */
634 *lplpvp = (LPDIRECT3DVIEWPORT2)This->current_viewport;
641 static HRESULT WINAPI IDirect3DDevice2Impl_SetRenderTarget(LPDIRECT3DDEVICE2 iface,
642 LPDIRECTDRAWSURFACE lpdds,
645 ICOM_THIS(IDirect3DDevice2Impl,iface);
646 FIXME("(%p)->(%p,%08lx): stub\n", This, lpdds, dwFlags);
653 static HRESULT WINAPI IDirect3DDevice2Impl_GetRenderTarget(LPDIRECT3DDEVICE2 iface,
654 LPDIRECTDRAWSURFACE *lplpdds)
656 ICOM_THIS(IDirect3DDevice2Impl,iface);
657 FIXME("(%p)->(%p): stub\n", This, lplpdds);
659 /* Returns the current rendering target (the surface on wich we render) */
660 *lplpdds = (LPDIRECTDRAWSURFACE)This->surface;
667 static HRESULT WINAPI IDirect3DDevice2Impl_Begin(LPDIRECT3DDEVICE2 iface,
668 D3DPRIMITIVETYPE d3dp,
672 ICOM_THIS(IDirect3DDevice2Impl,iface);
673 FIXME("(%p)->(%d,%d,%08lx): stub\n", This, d3dp, d3dv, dwFlags);
680 static HRESULT WINAPI IDirect3DDevice2Impl_BeginIndexed(LPDIRECT3DDEVICE2 iface,
681 D3DPRIMITIVETYPE d3dp,
687 ICOM_THIS(IDirect3DDevice2Impl,iface);
688 FIXME("(%p)->(%d,%d,%p,%ld,%08lx): stub\n", This, d3dp, d3dv, lpvert, numvert, dwFlags);
695 static HRESULT WINAPI IDirect3DDevice2Impl_Vertex(LPDIRECT3DDEVICE2 iface,
698 ICOM_THIS(IDirect3DDevice2Impl,iface);
699 FIXME("(%p)->(%p): stub\n", This, lpvert);
706 static HRESULT WINAPI IDirect3DDevice2Impl_Index(LPDIRECT3DDEVICE2 iface,
709 ICOM_THIS(IDirect3DDevice2Impl,iface);
710 FIXME("(%p)->(%d): stub\n", This, index);
717 static HRESULT WINAPI IDirect3DDevice2Impl_End(LPDIRECT3DDEVICE2 iface,
720 ICOM_THIS(IDirect3DDevice2Impl,iface);
721 FIXME("(%p)->(%08lx): stub\n", This, dwFlags);
729 static HRESULT WINAPI IDirect3DDevice2Impl_GetRenderState(LPDIRECT3DDEVICE2 iface,
730 D3DRENDERSTATETYPE d3drs,
733 ICOM_THIS(IDirect3DDevice2Impl,iface);
734 FIXME("(%p)->(%d,%p): stub\n", This, d3drs, lprstate);
741 static HRESULT WINAPI IDirect3DDevice2Impl_SetRenderState(LPDIRECT3DDEVICE2 iface,
742 D3DRENDERSTATETYPE dwRenderStateType,
745 ICOM_THIS(IDirect3DDevice2Impl,iface);
746 OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) This;
748 TRACE("(%p)->(%d,%ld)\n", This, dwRenderStateType, dwRenderState);
750 /* Call the render state functions */
751 set_render_state(dwRenderStateType, dwRenderState, &(odev->rs));
758 static HRESULT WINAPI IDirect3DDevice2Impl_GetLightState(LPDIRECT3DDEVICE2 iface,
759 D3DLIGHTSTATETYPE d3dls,
762 ICOM_THIS(IDirect3DDevice2Impl,iface);
763 FIXME("(%p)->(%d,%p): stub\n", This, d3dls, lplstate);
770 static HRESULT WINAPI IDirect3DDevice2Impl_SetLightState(LPDIRECT3DDEVICE2 iface,
771 D3DLIGHTSTATETYPE dwLightStateType,
774 ICOM_THIS(IDirect3DDevice2Impl,iface);
775 FIXME("(%p)->(%d,%08lx): stub\n", This, dwLightStateType, dwLightState);
777 switch (dwLightStateType) {
778 case D3DLIGHTSTATE_MATERIAL: { /* 1 */
779 IDirect3DMaterial2Impl* mat = (IDirect3DMaterial2Impl*) dwLightState;
786 TRACE("Zoups !!!\n");
790 case D3DLIGHTSTATE_AMBIENT: { /* 2 */
793 light[0] = ((dwLightState >> 16) & 0xFF) / 255.0;
794 light[1] = ((dwLightState >> 8) & 0xFF) / 255.0;
795 light[2] = ((dwLightState >> 0) & 0xFF) / 255.0;
798 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (float *) light);
802 case D3DLIGHTSTATE_COLORMODEL: /* 3 */
805 case D3DLIGHTSTATE_FOGMODE: /* 4 */
808 case D3DLIGHTSTATE_FOGSTART: /* 5 */
811 case D3DLIGHTSTATE_FOGEND: /* 6 */
814 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */
818 TRACE("Unexpected Light State Type\n");
819 return DDERR_INVALIDPARAMS;
827 static HRESULT WINAPI IDirect3DDevice2Impl_SetTransform(LPDIRECT3DDEVICE2 iface,
828 D3DTRANSFORMSTATETYPE d3dts,
829 LPD3DMATRIX lpmatrix)
831 ICOM_THIS(IDirect3DDevice2Impl,iface);
832 OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) This;
834 FIXME("(%p)->(%d,%p): stub\n", This, d3dts, lpmatrix);
838 /* Using a trial and failure approach, I found that the order of
839 Direct3D transformations that works best is :
841 ScreenCoord = ProjectionMat * ViewMat * WorldMat * ObjectCoord
843 As OpenGL uses only two matrices, I combined PROJECTION and VIEW into
844 OpenGL's GL_PROJECTION matrix and the WORLD into GL_MODELVIEW.
846 If anyone has a good explanation of the three different matrices in
847 the SDK online documentation, feel free to point it to me. For example,
848 which matrices transform lights ? In OpenGL only the PROJECTION matrix
849 transform the lights, not the MODELVIEW. Using the matrix names, I
850 supposed that PROJECTION and VIEW (all 'camera' related names) do
851 transform lights, but WORLD do not. It may be wrong though... */
853 /* After reading through both OpenGL and Direct3D documentations, I
854 thought that D3D matrices were written in 'line major mode' transposed
855 from OpenGL's 'column major mode'. But I found out that a simple memcpy
856 works fine to transfer one matrix format to the other (it did not work
857 when transposing)....
860 1) are the documentations wrong
861 2) does the matrix work even if they are not read correctly
862 3) is Mesa's implementation of OpenGL not compliant regarding Matrix
863 loading using glLoadMatrix ?
865 Anyway, I always use 'conv_mat' to transfer the matrices from one format
866 to the other so that if I ever find out that I need to transpose them, I
867 will able to do it quickly, only by changing the macro conv_mat. */
870 case D3DTRANSFORMSTATE_WORLD: {
871 conv_mat(lpmatrix, odev->world_mat);
872 glMatrixMode(GL_MODELVIEW);
873 glLoadMatrixf((float *) &(odev->world_mat));
876 case D3DTRANSFORMSTATE_VIEW: {
877 conv_mat(lpmatrix, odev->view_mat);
878 glMatrixMode(GL_PROJECTION);
879 glLoadMatrixf((float *) &(odev->proj_mat));
880 glMultMatrixf((float *) &(odev->view_mat));
883 case D3DTRANSFORMSTATE_PROJECTION: {
884 conv_mat(lpmatrix, odev->proj_mat);
885 glMatrixMode(GL_PROJECTION);
886 glLoadMatrixf((float *) &(odev->proj_mat));
887 glMultMatrixf((float *) &(odev->view_mat));
901 static HRESULT WINAPI IDirect3DDevice2Impl_GetTransform(LPDIRECT3DDEVICE2 iface,
902 D3DTRANSFORMSTATETYPE d3dts,
903 LPD3DMATRIX lpmatrix)
905 ICOM_THIS(IDirect3DDevice2Impl,iface);
906 FIXME("(%p)->(%d,%p): stub\n", This, d3dts, lpmatrix);
913 static HRESULT WINAPI IDirect3DDevice2Impl_MultiplyTransform(LPDIRECT3DDEVICE2 iface,
914 D3DTRANSFORMSTATETYPE d3dts,
915 LPD3DMATRIX lpmatrix)
917 ICOM_THIS(IDirect3DDevice2Impl,iface);
918 FIXME("(%p)->(%d,%p): stub\n", This, d3dts, lpmatrix);
923 #define DRAW_PRIMITIVE(MAXVERT,INDEX) \
924 /* Puts GL in the correct lighting mode */ \
925 if (odev->vt != d3dv) { \
926 if (odev->vt == D3DVT_TLVERTEX) { \
927 /* Need to put the correct transformation again */ \
928 glMatrixMode(GL_MODELVIEW); \
929 glLoadMatrixf((float *) &(odev->world_mat)); \
930 glMatrixMode(GL_PROJECTION); \
931 glLoadMatrixf((float *) &(odev->proj_mat)); \
932 glMultMatrixf((float *) &(odev->view_mat)); \
937 TRACE("Standard Vertex\n"); \
938 glEnable(GL_LIGHTING); \
941 case D3DVT_LVERTEX: \
942 TRACE("Lighted Vertex\n"); \
943 glDisable(GL_LIGHTING); \
946 case D3DVT_TLVERTEX: { \
947 GLdouble height, width, minZ, maxZ; \
949 TRACE("Transformed - Lighted Vertex\n"); \
950 /* First, disable lighting */ \
951 glDisable(GL_LIGHTING); \
953 /* Then do not put any transformation matrixes */ \
954 glMatrixMode(GL_MODELVIEW); \
956 glMatrixMode(GL_PROJECTION); \
959 if (This->current_viewport == NULL) { \
960 ERR("No current viewport !\n"); \
961 /* Using standard values */ \
967 if (This->current_viewport->use_vp2) { \
968 height = (GLdouble) This->current_viewport->viewport.vp2.dwHeight; \
969 width = (GLdouble) This->current_viewport->viewport.vp2.dwWidth; \
970 minZ = (GLdouble) This->current_viewport->viewport.vp2.dvMinZ; \
971 maxZ = (GLdouble) This->current_viewport->viewport.vp2.dvMaxZ; \
973 height = (GLdouble) This->current_viewport->viewport.vp1.dwHeight; \
974 width = (GLdouble) This->current_viewport->viewport.vp1.dwWidth; \
975 minZ = (GLdouble) This->current_viewport->viewport.vp1.dvMinZ; \
976 maxZ = (GLdouble) This->current_viewport->viewport.vp1.dvMaxZ; \
980 glOrtho(0.0, width, height, 0.0, -minZ, -maxZ); \
984 ERR("Unhandled vertex type\n"); \
992 case D3DPT_POINTLIST: \
993 TRACE("Start POINTS\n"); \
994 glBegin(GL_POINTS); \
997 case D3DPT_LINELIST: \
998 TRACE("Start LINES\n"); \
1002 case D3DPT_LINESTRIP: \
1003 TRACE("Start LINE_STRIP\n"); \
1004 glBegin(GL_LINE_STRIP); \
1007 case D3DPT_TRIANGLELIST: \
1008 TRACE("Start TRIANGLES\n"); \
1009 glBegin(GL_TRIANGLES); \
1012 case D3DPT_TRIANGLESTRIP: \
1013 TRACE("Start TRIANGLE_STRIP\n"); \
1014 glBegin(GL_TRIANGLE_STRIP); \
1017 case D3DPT_TRIANGLEFAN: \
1018 TRACE("Start TRIANGLE_FAN\n"); \
1019 glBegin(GL_TRIANGLE_FAN); \
1023 TRACE("Unhandled primitive\n"); \
1027 /* Draw the primitives */ \
1028 for (vx_index = 0; vx_index < MAXVERT; vx_index++) { \
1030 case D3DVT_VERTEX: { \
1031 D3DVERTEX *vx = ((D3DVERTEX *) lpvertex) + INDEX; \
1033 glNormal3f(vx->nx.nx, vx->ny.ny, vx->nz.nz); \
1034 glVertex3f(vx->x.x, vx->y.y, vx->z.z); \
1035 TRACE(" V: %f %f %f\n", vx->x.x, vx->y.y, vx->z.z); \
1038 case D3DVT_LVERTEX: { \
1039 D3DLVERTEX *vx = ((D3DLVERTEX *) lpvertex) + INDEX; \
1040 DWORD col = vx->c.color; \
1042 glColor3f(((col >> 16) & 0xFF) / 255.0, \
1043 ((col >> 8) & 0xFF) / 255.0, \
1044 ((col >> 0) & 0xFF) / 255.0); \
1045 glVertex3f(vx->x.x, vx->y.y, vx->z.z); \
1046 TRACE(" LV: %f %f %f (%02lx %02lx %02lx)\n", \
1047 vx->x.x, vx->y.y, vx->z.z, \
1048 ((col >> 16) & 0xFF), ((col >> 8) & 0xFF), ((col >> 0) & 0xFF)); \
1051 case D3DVT_TLVERTEX: { \
1052 D3DTLVERTEX *vx = ((D3DTLVERTEX *) lpvertex) + INDEX; \
1053 DWORD col = vx->c.color; \
1055 glColor3f(((col >> 16) & 0xFF) / 255.0, \
1056 ((col >> 8) & 0xFF) / 255.0, \
1057 ((col >> 0) & 0xFF) / 255.0); \
1058 glTexCoord2f(vx->u.tu, vx->v.tv); \
1059 if (vx->r.rhw < 0.01) \
1060 glVertex3f(vx->x.sx, \
1064 glVertex4f(vx->x.sx / vx->r.rhw, \
1065 vx->y.sy / vx->r.rhw, \
1066 vx->z.sz / vx->r.rhw, \
1068 TRACE(" TLV: %f %f %f (%02lx %02lx %02lx) (%f %f) (%f)\n", \
1069 vx->x.sx, vx->y.sy, vx->z.sz, \
1070 ((col >> 16) & 0xFF), ((col >> 8) & 0xFF), ((col >> 0) & 0xFF), \
1071 vx->u.tu, vx->v.tv, vx->r.rhw); \
1075 TRACE("Unhandled vertex type\n"); \
1084 static HRESULT WINAPI IDirect3DDevice2Impl_DrawPrimitive(LPDIRECT3DDEVICE2 iface,
1085 D3DPRIMITIVETYPE d3dp,
1091 ICOM_THIS(IDirect3DDevice2Impl,iface);
1092 OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) This;
1095 TRACE("(%p)->(%d,%d,%p,%ld,%08lx): stub\n", This, d3dp, d3dv, lpvertex, vertcount, dwFlags);
1098 DRAW_PRIMITIVE(vertcount, vx_index);
1106 static HRESULT WINAPI IDirect3DDevice2Impl_DrawIndexedPrimitive(LPDIRECT3DDEVICE2 iface,
1107 D3DPRIMITIVETYPE d3dp,
1115 ICOM_THIS(IDirect3DDevice2Impl,iface);
1116 OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) This;
1119 TRACE("(%p)->(%d,%d,%p,%ld,%p,%ld,%08lx): stub\n", This, d3dp, d3dv, lpvertex, vertcount, lpindexes, indexcount, dwFlags);
1122 DRAW_PRIMITIVE(indexcount, lpindexes[vx_index]);
1130 static HRESULT WINAPI IDirect3DDevice2Impl_SetClipStatus(LPDIRECT3DDEVICE2 iface,
1131 LPD3DCLIPSTATUS lpcs)
1133 ICOM_THIS(IDirect3DDevice2Impl,iface);
1134 FIXME("(%p)->(%p): stub\n", This, lpcs);
1141 static HRESULT WINAPI IDirect3DDevice2Impl_GetClipStatus(LPDIRECT3DDEVICE2 iface,
1142 LPD3DCLIPSTATUS lpcs)
1144 ICOM_THIS(IDirect3DDevice2Impl,iface);
1145 FIXME("(%p)->(%p): stub\n", This, lpcs);
1152 /*******************************************************************************
1153 * OpenGL-specific IDirect3DDevice2
1156 /*******************************************************************************
1157 * OpenGL-specific VTable
1160 static ICOM_VTABLE(IDirect3DDevice2) OpenGL_vtable =
1162 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1163 IDirect3DDevice2Impl_QueryInterface,
1164 IDirect3DDevice2Impl_AddRef,
1165 IDirect3DDevice2Impl_Release,
1166 /*** IDirect3DDevice2 methods ***/
1167 IDirect3DDevice2Impl_GetCaps,
1168 IDirect3DDevice2Impl_SwapTextureHandles,
1169 IDirect3DDevice2Impl_GetStats,
1170 IDirect3DDevice2Impl_AddViewport,
1171 IDirect3DDevice2Impl_DeleteViewport,
1172 IDirect3DDevice2Impl_NextViewport,
1173 IDirect3DDevice2Impl_EnumTextureFormats,
1174 IDirect3DDevice2Impl_BeginScene,
1175 IDirect3DDevice2Impl_EndScene,
1176 IDirect3DDevice2Impl_GetDirect3D,
1178 /*** DrawPrimitive API ***/
1179 IDirect3DDevice2Impl_SetCurrentViewport,
1180 IDirect3DDevice2Impl_GetCurrentViewport,
1182 IDirect3DDevice2Impl_SetRenderTarget,
1183 IDirect3DDevice2Impl_GetRenderTarget,
1185 IDirect3DDevice2Impl_Begin,
1186 IDirect3DDevice2Impl_BeginIndexed,
1187 IDirect3DDevice2Impl_Vertex,
1188 IDirect3DDevice2Impl_Index,
1189 IDirect3DDevice2Impl_End,
1191 IDirect3DDevice2Impl_GetRenderState,
1192 IDirect3DDevice2Impl_SetRenderState,
1193 IDirect3DDevice2Impl_GetLightState,
1194 IDirect3DDevice2Impl_SetLightState,
1195 IDirect3DDevice2Impl_SetTransform,
1196 IDirect3DDevice2Impl_GetTransform,
1197 IDirect3DDevice2Impl_MultiplyTransform,
1199 IDirect3DDevice2Impl_DrawPrimitive,
1200 IDirect3DDevice2Impl_DrawIndexedPrimitive,
1202 IDirect3DDevice2Impl_SetClipStatus,
1203 IDirect3DDevice2Impl_GetClipStatus,
1206 /*******************************************************************************
1209 int d3d_OpenGL_dx3(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) {
1210 D3DDEVICEDESC d1,d2;
1212 TRACE(" Enumerating OpenGL D3D device.\n");
1214 fill_opengl_caps(&d1, &d2);
1216 return cb((void*)&IID_D3DDEVICE_OpenGL,"WINE Direct3D using OpenGL","direct3d",&d1,&d2,context);
1219 float id_mat[16] = {
1226 int is_OpenGL_dx3(REFCLSID rguid, IDirectDrawSurfaceImpl* surface, IDirect3DDeviceImpl** device)
1228 if (!memcmp(&IID_D3DDEVICE_OpenGL,rguid,sizeof(IID_D3DDEVICE_OpenGL))) {
1229 OpenGL_IDirect3DDevice *odev;
1231 int attributeList[]={ GLX_RGBA, GLX_DEPTH_SIZE, 16, GLX_DOUBLEBUFFER, None };
1235 *device = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(OpenGL_IDirect3DDevice));
1236 odev = (OpenGL_IDirect3DDevice *) (*device);
1238 (*device)->lpvtbl = &OpenGL_vtable_dx3;
1239 (*device)->d3d = NULL;
1240 (*device)->surface = surface;
1242 (*device)->viewport_list = NULL;
1243 (*device)->current_viewport = NULL;
1245 (*device)->set_context = set_context_dx3;
1247 TRACE("OpenGL device created \n");
1249 /* Create the OpenGL context */
1251 odev->ctx = OSMesaCreateContext(OSMESA_RGBA, NULL);
1252 odev->buffer = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
1253 surface->s.surface_desc.dwWidth * surface->s.surface_desc.dwHeight * 4);
1255 /* First get the correct visual */
1256 TRACE("Backbuffer : %d\n", surface->s.backbuffer == NULL);
1257 /* if (surface->s.backbuffer == NULL)
1258 attributeList[3] = None; */
1260 xvis = glXChooseVisual(display,
1261 DefaultScreen(display),
1264 ERR("No visual found !\n");
1266 TRACE("Visual found\n");
1267 /* Create the context */
1268 odev->ctx = glXCreateContext(display,
1272 TRACE("Context created\n");
1274 /* Now override the surface's Flip method (if in double buffering) */
1275 surface->s.d3d_device = (void *) odev;
1276 if (surface->s.backbuffer != NULL)
1277 surface->s.backbuffer->s.d3d_device = (void *) odev;
1279 odev->rs.src = GL_ONE;
1280 odev->rs.dst = GL_ZERO;
1281 odev->rs.mag = GL_NEAREST;
1282 odev->rs.min = GL_NEAREST;
1284 odev->world_mat = (LPD3DMATRIX) &id_mat;
1285 odev->view_mat = (LPD3DMATRIX) &id_mat;
1286 odev->proj_mat = (LPD3DMATRIX) &id_mat;
1288 /* Initialisation */
1289 (*device)->set_context(*device);
1290 glClearColor(0.0, 0.0, 0.0, 0.0);
1291 glColor3f(1.0, 1.0, 1.0);
1296 /* This is not the OpenGL UID */
1301 /*******************************************************************************
1304 static HRESULT WINAPI IDirect3DDeviceImpl_QueryInterface(LPDIRECT3DDEVICE iface,
1308 ICOM_THIS(IDirect3DDeviceImpl,iface);
1311 WINE_StringFromCLSID((LPCLSID)riid,xrefiid);
1312 FIXME("(%p)->(%s,%p): stub\n", This, xrefiid,ppvObj);
1319 static ULONG WINAPI IDirect3DDeviceImpl_AddRef(LPDIRECT3DDEVICE iface)
1321 ICOM_THIS(IDirect3DDeviceImpl,iface);
1322 TRACE("(%p)->()incrementing from %lu.\n", This, This->ref );
1324 return ++(This->ref);
1329 static ULONG WINAPI IDirect3DDeviceImpl_Release(LPDIRECT3DDEVICE iface)
1331 ICOM_THIS(IDirect3DDeviceImpl,iface);
1332 FIXME("(%p)->() decrementing from %lu.\n", This, This->ref );
1334 if (!--(This->ref)) {
1335 OpenGL_IDirect3DDevice *odev = (OpenGL_IDirect3DDevice *) This;
1338 OSMesaDestroyContext(odev->ctx);
1341 glXDestroyContext(display,
1346 HeapFree(GetProcessHeap(),0,This);
1353 static HRESULT WINAPI IDirect3DDeviceImpl_Initialize(LPDIRECT3DDEVICE iface,
1356 LPD3DDEVICEDESC lpd3ddvdesc)
1358 ICOM_THIS(IDirect3DDeviceImpl,iface);
1359 TRACE("(%p)->(%p,%p,%p): stub\n", This, lpd3d,lpGUID, lpd3ddvdesc);
1361 return DDERR_ALREADYINITIALIZED;
1365 static HRESULT WINAPI IDirect3DDeviceImpl_GetCaps(LPDIRECT3DDEVICE iface,
1366 LPD3DDEVICEDESC lpD3DHWDevDesc,
1367 LPD3DDEVICEDESC lpD3DSWDevDesc)
1369 ICOM_THIS(IDirect3DDeviceImpl,iface);
1370 TRACE("(%p)->(%p,%p): stub\n", This, lpD3DHWDevDesc, lpD3DSWDevDesc);
1372 fill_opengl_caps(lpD3DHWDevDesc, lpD3DSWDevDesc);
1378 static HRESULT WINAPI IDirect3DDeviceImpl_SwapTextureHandles(LPDIRECT3DDEVICE iface,
1379 LPDIRECT3DTEXTURE lpD3DTex1,
1380 LPDIRECT3DTEXTURE lpD3DTex2)
1382 ICOM_THIS(IDirect3DDeviceImpl,iface);
1383 TRACE("(%p)->(%p,%p): stub\n", This, lpD3DTex1, lpD3DTex2);
1388 static HRESULT WINAPI IDirect3DDeviceImpl_CreateExecuteBuffer(LPDIRECT3DDEVICE iface,
1389 LPD3DEXECUTEBUFFERDESC lpDesc,
1390 LPDIRECT3DEXECUTEBUFFER *lplpDirect3DExecuteBuffer,
1391 IUnknown *pUnkOuter)
1393 ICOM_THIS(IDirect3DDeviceImpl,iface);
1394 TRACE("(%p)->(%p,%p,%p)\n", This, lpDesc, lplpDirect3DExecuteBuffer, pUnkOuter);
1396 *lplpDirect3DExecuteBuffer = d3dexecutebuffer_create(This, lpDesc);
1402 static HRESULT WINAPI IDirect3DDeviceImpl_GetStats(LPDIRECT3DDEVICE iface,
1403 LPD3DSTATS lpD3DStats)
1405 ICOM_THIS(IDirect3DDeviceImpl,iface);
1406 TRACE("(%p)->(%p): stub\n", This, lpD3DStats);
1412 static HRESULT WINAPI IDirect3DDeviceImpl_Execute(LPDIRECT3DDEVICE iface,
1413 LPDIRECT3DEXECUTEBUFFER lpDirect3DExecuteBuffer,
1414 LPDIRECT3DVIEWPORT lpDirect3DViewport,
1417 ICOM_THIS(IDirect3DDeviceImpl,iface);
1418 TRACE("(%p)->(%p,%p,%08ld): stub\n", This, lpDirect3DExecuteBuffer, lpDirect3DViewport, dwFlags);
1420 /* Put this as the default context */
1423 ((IDirect3DExecuteBufferImpl*)lpDirect3DExecuteBuffer)->execute(lpDirect3DExecuteBuffer, iface, lpDirect3DViewport);
1428 static HRESULT WINAPI IDirect3DDeviceImpl_AddViewport(LPDIRECT3DDEVICE iface,
1429 LPDIRECT3DVIEWPORT lpvp)
1431 ICOM_THIS(IDirect3DDeviceImpl,iface);
1432 IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
1433 FIXME("(%p)->(%p): stub\n", This, ilpvp);
1435 /* Adds this viewport to the viewport list */
1436 ilpvp->next = This->viewport_list;
1437 This->viewport_list = ilpvp;
1444 static HRESULT WINAPI IDirect3DDeviceImpl_DeleteViewport(LPDIRECT3DDEVICE iface,
1445 LPDIRECT3DVIEWPORT lpvp)
1447 ICOM_THIS(IDirect3DDeviceImpl,iface);
1448 IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
1449 IDirect3DViewport2Impl *cur, *prev;
1450 FIXME("(%p)->(%p): stub\n", This, lpvp);
1452 /* Finds this viewport in the list */
1454 cur = This->viewport_list;
1455 while ((cur != NULL) && (cur != ilpvp)) {
1460 return DDERR_INVALIDOBJECT;
1464 This->viewport_list = cur->next;
1466 prev->next = cur->next;
1473 static HRESULT WINAPI IDirect3DDeviceImpl_NextViewport(LPDIRECT3DDEVICE iface,
1474 LPDIRECT3DVIEWPORT lpvp,
1475 LPDIRECT3DVIEWPORT* lplpvp,
1478 ICOM_THIS(IDirect3DDeviceImpl,iface);
1479 IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
1480 IDirect3DViewport2Impl** ilplpvp=(IDirect3DViewport2Impl**)lplpvp;
1481 FIXME("(%p)->(%p,%p,%08lx): stub\n", This, ilpvp, ilplpvp, dwFlags);
1485 *ilplpvp = ilpvp->next;
1489 *ilplpvp = This->viewport_list;
1493 ilpvp = This->viewport_list;
1494 while (ilpvp->next != NULL)
1495 ilpvp = ilpvp->next;
1501 return DDERR_INVALIDPARAMS;
1507 static HRESULT WINAPI IDirect3DDeviceImpl_Pick(LPDIRECT3DDEVICE iface,
1508 LPDIRECT3DEXECUTEBUFFER lpDirect3DExecuteBuffer,
1509 LPDIRECT3DVIEWPORT lpDirect3DViewport,
1513 ICOM_THIS(IDirect3DDeviceImpl,iface);
1514 TRACE("(%p)->(%p,%p,%08lx,%p): stub\n", This, lpDirect3DExecuteBuffer, lpDirect3DViewport,
1521 static HRESULT WINAPI IDirect3DDeviceImpl_GetPickRecords(LPDIRECT3DDEVICE iface,
1523 LPD3DPICKRECORD lpD3DPickRec)
1525 ICOM_THIS(IDirect3DDeviceImpl,iface);
1526 TRACE("(%p)->(%p,%p): stub\n", This, lpCount, lpD3DPickRec);
1532 static HRESULT WINAPI IDirect3DDeviceImpl_EnumTextureFormats(LPDIRECT3DDEVICE iface,
1533 LPD3DENUMTEXTUREFORMATSCALLBACK lpd3dEnumTextureProc,
1536 ICOM_THIS(IDirect3DDeviceImpl,iface);
1537 TRACE("(%p)->(%p,%p): stub\n", This, lpd3dEnumTextureProc, lpArg);
1539 return enum_texture_format_OpenGL(lpd3dEnumTextureProc, lpArg);
1543 static HRESULT WINAPI IDirect3DDeviceImpl_CreateMatrix(LPDIRECT3DDEVICE iface,
1544 LPD3DMATRIXHANDLE lpD3DMatHandle)
1546 ICOM_THIS(IDirect3DDeviceImpl,iface);
1547 TRACE("(%p)->(%p)\n", This, lpD3DMatHandle);
1549 *lpD3DMatHandle = (D3DMATRIXHANDLE) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(D3DMATRIX));
1555 static HRESULT WINAPI IDirect3DDeviceImpl_SetMatrix(LPDIRECT3DDEVICE iface,
1556 D3DMATRIXHANDLE d3dMatHandle,
1557 const LPD3DMATRIX lpD3DMatrix)
1559 ICOM_THIS(IDirect3DDeviceImpl,iface);
1560 TRACE("(%p)->(%08lx,%p)\n", This, d3dMatHandle, lpD3DMatrix);
1562 dump_mat(lpD3DMatrix);
1564 *((D3DMATRIX *) d3dMatHandle) = *lpD3DMatrix;
1570 static HRESULT WINAPI IDirect3DDeviceImpl_GetMatrix(LPDIRECT3DDEVICE iface,
1571 D3DMATRIXHANDLE D3DMatHandle,
1572 LPD3DMATRIX lpD3DMatrix)
1574 ICOM_THIS(IDirect3DDeviceImpl,iface);
1575 TRACE("(%p)->(%08lx,%p)\n", This, D3DMatHandle, lpD3DMatrix);
1577 *lpD3DMatrix = *((D3DMATRIX *) D3DMatHandle);
1583 static HRESULT WINAPI IDirect3DDeviceImpl_DeleteMatrix(LPDIRECT3DDEVICE iface,
1584 D3DMATRIXHANDLE d3dMatHandle)
1586 ICOM_THIS(IDirect3DDeviceImpl,iface);
1587 TRACE("(%p)->(%08lx)\n", This, d3dMatHandle);
1589 HeapFree(GetProcessHeap(),0, (void *) d3dMatHandle);
1595 static HRESULT WINAPI IDirect3DDeviceImpl_BeginScene(LPDIRECT3DDEVICE iface)
1597 ICOM_THIS(IDirect3DDeviceImpl,iface);
1598 /* OpenGL_IDirect3DDevice *odev = (OpenGL_IDirect3DDevice *) This; */
1600 FIXME("(%p)->(): stub\n", This);
1602 /* We get the pointer to the surface (should be done on flip) */
1603 /* odev->zb->pbuf = This->surface->s.surface_desc.y.lpSurface; */
1609 /* This is for the moment copy-pasted from IDirect3DDevice2...
1610 Will make a common function ... */
1611 static HRESULT WINAPI IDirect3DDeviceImpl_EndScene(LPDIRECT3DDEVICE iface)
1613 ICOM_THIS(IDirect3DDeviceImpl,iface);
1615 OpenGL_IDirect3DDevice *odev = (OpenGL_IDirect3DDevice *) This;
1616 LPDIRECTDRAWSURFACE3 surf = (LPDIRECTDRAWSURFACE3) This->surface;
1617 DDSURFACEDESC sdesc;
1620 unsigned short *dest;
1623 FIXME("(%p)->(): stub\n", This);
1626 /* Here we copy back the OpenGL scene to the the DDraw surface */
1627 /* First, lock the surface */
1628 IDirectDrawSurface3_Lock(surf,NULL,&sdesc,DDLOCK_WRITEONLY,0);
1630 /* The copy the OpenGL buffer to this surface */
1632 /* NOTE : this is only for debugging purpose. I KNOW it is really unoptimal.
1633 I am currently working on a set of patches for Mesa to have OSMesa support
1634 16 bpp surfaces => we will able to render directly onto the surface, no
1635 need to do a bpp conversion */
1636 dest = (unsigned short *) sdesc.y.lpSurface;
1637 src = ((unsigned char *) odev->buffer) + 4 * (sdesc.dwWidth * (sdesc.dwHeight - 1));
1638 for (y = 0; y < sdesc.dwHeight; y++) {
1639 unsigned char *lsrc = src;
1641 for (x = 0; x < sdesc.dwWidth ; x++) {
1642 unsigned char r = *lsrc++;
1643 unsigned char g = *lsrc++;
1644 unsigned char b = *lsrc++;
1647 *dest = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
1652 src -= 4 * sdesc.dwWidth;
1655 /* Unlock the surface */
1656 IDirectDrawSurface3_Unlock(surf,sdesc.y.lpSurface);
1658 /* No need to do anything here... */
1665 static HRESULT WINAPI IDirect3DDeviceImpl_GetDirect3D(LPDIRECT3DDEVICE iface,
1666 LPDIRECT3D *lpDirect3D)
1668 ICOM_THIS(IDirect3DDeviceImpl,iface);
1669 TRACE("(%p)->(%p): stub\n", This, lpDirect3D);
1676 /*******************************************************************************
1677 * Direct3DDevice VTable
1679 static ICOM_VTABLE(IDirect3DDevice) OpenGL_vtable_dx3 =
1681 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1682 IDirect3DDeviceImpl_QueryInterface,
1683 IDirect3DDeviceImpl_AddRef,
1684 IDirect3DDeviceImpl_Release,
1685 IDirect3DDeviceImpl_Initialize,
1686 IDirect3DDeviceImpl_GetCaps,
1687 IDirect3DDeviceImpl_SwapTextureHandles,
1688 IDirect3DDeviceImpl_CreateExecuteBuffer,
1689 IDirect3DDeviceImpl_GetStats,
1690 IDirect3DDeviceImpl_Execute,
1691 IDirect3DDeviceImpl_AddViewport,
1692 IDirect3DDeviceImpl_DeleteViewport,
1693 IDirect3DDeviceImpl_NextViewport,
1694 IDirect3DDeviceImpl_Pick,
1695 IDirect3DDeviceImpl_GetPickRecords,
1696 IDirect3DDeviceImpl_EnumTextureFormats,
1697 IDirect3DDeviceImpl_CreateMatrix,
1698 IDirect3DDeviceImpl_SetMatrix,
1699 IDirect3DDeviceImpl_GetMatrix,
1700 IDirect3DDeviceImpl_DeleteMatrix,
1701 IDirect3DDeviceImpl_BeginScene,
1702 IDirect3DDeviceImpl_EndScene,
1703 IDirect3DDeviceImpl_GetDirect3D,
1706 #else /* HAVE_MESAGL */
1708 int d3d_OpenGL(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) {
1712 int is_OpenGL(REFCLSID rguid, IDirectDrawSurfaceImpl* surface, IDirect3DDevice2Impl** device, IDirect3D2Impl* d3d)
1717 int d3d_OpenGL_dx3(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) {
1721 int is_OpenGL_dx3(REFCLSID rguid, IDirectDrawSurfaceImpl* surface, IDirect3DDeviceImpl** device)
1726 #endif /* HAVE_MESAGL */