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 /* if (surface->s.backbuffer == NULL)
197 attributeList[3] = None; */
199 xvis = glXChooseVisual(display,
200 DefaultScreen(display),
203 ERR("No visual found !\n");
205 TRACE("Visual found\n");
206 /* Create the context */
207 odev->ctx = glXCreateContext(display,
211 if (odev->ctx == NULL)
212 ERR("Error in context creation !\n");
214 TRACE("Context created (%p)\n", odev->ctx);
216 /* Now override the surface's Flip method (if in double buffering) */
217 surface->s.d3d_device = (void *) odev;
220 struct _surface_chain *chain = surface->s.chain;
221 for (i=0;i<chain->nrofsurfaces;i++)
222 if (chain->surfaces[i]->s.surface_desc.ddsCaps.dwCaps & DDSCAPS_FLIP)
223 chain->surfaces[i]->s.d3d_device = (void *) odev;
226 odev->rs.src = GL_ONE;
227 odev->rs.dst = GL_ZERO;
228 odev->rs.mag = GL_NEAREST;
229 odev->rs.min = GL_NEAREST;
232 memcpy(odev->world_mat, id_mat, 16 * sizeof(float));
233 memcpy(odev->view_mat , id_mat, 16 * sizeof(float));
234 memcpy(odev->proj_mat , id_mat, 16 * sizeof(float));
237 TRACE("Setting current context\n");
238 (*device)->set_context(*device);
239 TRACE("Current context set\n");
240 glClearColor(0.0, 0.0, 0.0, 0.0);
241 glColor3f(1.0, 1.0, 1.0);
244 TRACE("OpenGL device created \n");
249 /* This is not the OpenGL UID */
253 /*******************************************************************************
254 * Common IDirect3DDevice2
257 static HRESULT WINAPI IDirect3DDevice2Impl_QueryInterface(LPDIRECT3DDEVICE2 iface,
261 ICOM_THIS(IDirect3DDevice2Impl,iface);
264 WINE_StringFromCLSID((LPCLSID)riid,xrefiid);
265 FIXME("(%p)->(%s,%p): stub\n", This, xrefiid,ppvObj);
272 static ULONG WINAPI IDirect3DDevice2Impl_AddRef(LPDIRECT3DDEVICE2 iface)
274 ICOM_THIS(IDirect3DDevice2Impl,iface);
275 TRACE("(%p)->()incrementing from %lu.\n", This, This->ref );
277 return ++(This->ref);
282 static ULONG WINAPI IDirect3DDevice2Impl_Release(LPDIRECT3DDEVICE2 iface)
284 ICOM_THIS(IDirect3DDevice2Impl,iface);
285 FIXME("(%p)->() decrementing from %lu.\n", This, This->ref );
287 if (!--(This->ref)) {
288 OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) This;
291 OSMesaDestroyContext(odev->ctx);
294 glXDestroyContext(display,
299 HeapFree(GetProcessHeap(),0,This);
307 /*** IDirect3DDevice2 methods ***/
308 static HRESULT WINAPI IDirect3DDevice2Impl_GetCaps(LPDIRECT3DDEVICE2 iface,
309 LPD3DDEVICEDESC lpdescsoft,
310 LPD3DDEVICEDESC lpdeschard)
312 ICOM_THIS(IDirect3DDevice2Impl,iface);
313 FIXME("(%p)->(%p,%p): stub\n", This, lpdescsoft, lpdeschard);
315 fill_opengl_caps(lpdescsoft, lpdeschard);
322 static HRESULT WINAPI IDirect3DDevice2Impl_SwapTextureHandles(LPDIRECT3DDEVICE2 iface,
323 LPDIRECT3DTEXTURE2 lptex1,
324 LPDIRECT3DTEXTURE2 lptex2)
326 ICOM_THIS(IDirect3DDevice2Impl,iface);
327 FIXME("(%p)->(%p,%p): stub\n", This, lptex1, lptex2);
334 static HRESULT WINAPI IDirect3DDevice2Impl_GetStats(LPDIRECT3DDEVICE2 iface,
337 ICOM_THIS(IDirect3DDevice2Impl,iface);
338 FIXME("(%p)->(%p): stub\n", This, lpstats);
345 static HRESULT WINAPI IDirect3DDevice2Impl_AddViewport(LPDIRECT3DDEVICE2 iface,
346 LPDIRECT3DVIEWPORT2 lpvp)
348 ICOM_THIS(IDirect3DDevice2Impl,iface);
349 IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
350 FIXME("(%p)->(%p): stub\n", This, ilpvp);
352 /* Adds this viewport to the viewport list */
353 ilpvp->next = This->viewport_list;
354 This->viewport_list = ilpvp;
361 static HRESULT WINAPI IDirect3DDevice2Impl_DeleteViewport(LPDIRECT3DDEVICE2 iface,
362 LPDIRECT3DVIEWPORT2 lpvp)
364 ICOM_THIS(IDirect3DDevice2Impl,iface);
365 IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
366 IDirect3DViewport2Impl *cur, *prev;
367 FIXME("(%p)->(%p): stub\n", This, lpvp);
369 /* Finds this viewport in the list */
371 cur = This->viewport_list;
372 while ((cur != NULL) && (cur != ilpvp)) {
377 return DDERR_INVALIDOBJECT;
381 This->viewport_list = cur->next;
383 prev->next = cur->next;
390 static HRESULT WINAPI IDirect3DDevice2Impl_NextViewport(LPDIRECT3DDEVICE2 iface,
391 LPDIRECT3DVIEWPORT2 lpvp,
392 LPDIRECT3DVIEWPORT2* lplpvp,
395 ICOM_THIS(IDirect3DDevice2Impl,iface);
396 IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
397 IDirect3DViewport2Impl** ilplpvp=(IDirect3DViewport2Impl**)lplpvp;
398 FIXME("(%p)->(%p,%p,%08lx): stub\n", This, lpvp, lpvp, dwFlags);
402 *ilplpvp = ilpvp->next;
406 *ilplpvp = This->viewport_list;
410 ilpvp = This->viewport_list;
411 while (ilpvp->next != NULL)
418 return DDERR_INVALIDPARAMS;
424 static HRESULT enum_texture_format_OpenGL(LPD3DENUMTEXTUREFORMATSCALLBACK cb,
427 LPDDPIXELFORMAT pformat;
429 /* Do the texture enumeration */
430 sdesc.dwSize = sizeof(DDSURFACEDESC);
431 sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
432 sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
433 pformat = &(sdesc.ddpfPixelFormat);
434 pformat->dwSize = sizeof(DDPIXELFORMAT);
435 pformat->dwFourCC = 0;
437 TRACE("Enumerating GL_RGBA unpacked (32)\n");
438 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
439 pformat->x.dwRGBBitCount = 32;
440 pformat->y.dwRBitMask = 0xFF000000;
441 pformat->z.dwGBitMask = 0x00FF0000;
442 pformat->xx.dwBBitMask = 0x0000FF00;
443 pformat->xy.dwRGBAlphaBitMask = 0x000000FF;
444 if (cb(&sdesc, context) == 0)
447 TRACE("Enumerating GL_RGB unpacked (24)\n");
448 pformat->dwFlags = DDPF_RGB;
449 pformat->x.dwRGBBitCount = 24;
450 pformat->y.dwRBitMask = 0x00FF0000;
451 pformat->z.dwGBitMask = 0x0000FF00;
452 pformat->xx.dwBBitMask = 0x000000FF;
453 pformat->xy.dwRGBAlphaBitMask = 0x00000000;
454 if (cb(&sdesc, context) == 0)
457 #ifndef HAVE_BUGGY_MESAGL
458 /* The packed texture format are buggy in Mesa. The bug was reported and corrected,
459 so that future version will work great. */
460 TRACE("Enumerating GL_RGB packed GL_UNSIGNED_SHORT_5_6_5 (16)\n");
461 pformat->dwFlags = DDPF_RGB;
462 pformat->x.dwRGBBitCount = 16;
463 pformat->y.dwRBitMask = 0x0000F800;
464 pformat->z.dwGBitMask = 0x000007E0;
465 pformat->xx.dwBBitMask = 0x0000001F;
466 pformat->xy.dwRGBAlphaBitMask = 0x00000000;
467 if (cb(&sdesc, context) == 0)
470 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_5_5_5_1 (16)\n");
471 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
472 pformat->x.dwRGBBitCount = 16;
473 pformat->y.dwRBitMask = 0x0000F800;
474 pformat->z.dwGBitMask = 0x000007C0;
475 pformat->xx.dwBBitMask = 0x0000003E;
476 pformat->xy.dwRGBAlphaBitMask = 0x00000001;
477 if (cb(&sdesc, context) == 0)
480 TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_4_4_4_4 (16)\n");
481 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
482 pformat->x.dwRGBBitCount = 16;
483 pformat->y.dwRBitMask = 0x0000F000;
484 pformat->z.dwGBitMask = 0x00000F00;
485 pformat->xx.dwBBitMask = 0x000000F0;
486 pformat->xy.dwRGBAlphaBitMask = 0x0000000F;
487 if (cb(&sdesc, context) == 0)
490 TRACE("Enumerating GL_RGB packed GL_UNSIGNED_BYTE_3_3_2 (8)\n");
491 pformat->dwFlags = DDPF_RGB;
492 pformat->x.dwRGBBitCount = 8;
493 pformat->y.dwRBitMask = 0x0000F800;
494 pformat->z.dwGBitMask = 0x000007C0;
495 pformat->xx.dwBBitMask = 0x0000003E;
496 pformat->xy.dwRGBAlphaBitMask = 0x00000001;
497 if (cb(&sdesc, context) == 0)
501 TRACE("Enumerating Paletted (8)\n");
502 pformat->dwFlags = DDPF_PALETTEINDEXED8;
503 pformat->x.dwRGBBitCount = 8;
504 pformat->y.dwRBitMask = 0x00000000;
505 pformat->z.dwGBitMask = 0x00000000;
506 pformat->xx.dwBBitMask = 0x00000000;
507 pformat->xy.dwRGBAlphaBitMask = 0x00000000;
508 if (cb(&sdesc, context) == 0)
511 TRACE("End of enumeration\n");
516 static HRESULT WINAPI IDirect3DDevice2Impl_EnumTextureFormats(LPDIRECT3DDEVICE2 iface,
517 LPD3DENUMTEXTUREFORMATSCALLBACK cb,
520 ICOM_THIS(IDirect3DDevice2Impl,iface);
521 FIXME("(%p)->(%p,%p): stub\n", This, cb, context);
523 return enum_texture_format_OpenGL(cb, context);
528 static HRESULT WINAPI IDirect3DDevice2Impl_BeginScene(LPDIRECT3DDEVICE2 iface)
530 ICOM_THIS(IDirect3DDevice2Impl,iface);
531 /* OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) This; */
533 FIXME("(%p)->(): stub\n", This);
535 /* Here, we should get the DDraw surface and 'copy it' to the
536 OpenGL surface.... */
543 static HRESULT WINAPI IDirect3DDevice2Impl_EndScene(LPDIRECT3DDEVICE2 iface)
545 ICOM_THIS(IDirect3DDevice2Impl,iface);
547 OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) This;
548 LPDIRECTDRAWSURFACE3 surf = (LPDIRECTDRAWSURFACE3) This->surface;
552 unsigned short *dest;
555 FIXME("(%p)->(): stub\n", This);
558 /* Here we copy back the OpenGL scene to the the DDraw surface */
559 /* First, lock the surface */
560 IDirectDrawSurface3_Lock(surf,NULL,&sdesc,DDLOCK_WRITEONLY,0);
562 /* The copy the OpenGL buffer to this surface */
564 /* NOTE : this is only for debugging purpose. I KNOW it is really unoptimal.
565 I am currently working on a set of patches for Mesa to have OSMesa support
566 16 bpp surfaces => we will able to render directly onto the surface, no
567 need to do a bpp conversion */
568 dest = (unsigned short *) sdesc.y.lpSurface;
569 src = ((unsigned char *) odev->buffer) + 4 * (sdesc.dwWidth * (sdesc.dwHeight - 1));
570 for (y = 0; y < sdesc.dwHeight; y++) {
571 unsigned char *lsrc = src;
573 for (x = 0; x < sdesc.dwWidth ; x++) {
574 unsigned char r = *lsrc++;
575 unsigned char g = *lsrc++;
576 unsigned char b = *lsrc++;
578 *dest = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
583 src -= 4 * sdesc.dwWidth;
586 /* Unlock the surface */
587 IDirectDrawSurface3_Unlock(surf,sdesc.y.lpSurface);
589 /* No need to do anything here... */
597 static HRESULT WINAPI IDirect3DDevice2Impl_GetDirect3D(LPDIRECT3DDEVICE2 iface, LPDIRECT3D2 *lpd3d2)
599 ICOM_THIS(IDirect3DDevice2Impl,iface);
600 TRACE("(%p)->(%p): stub\n", This, lpd3d2);
602 *lpd3d2 = (LPDIRECT3D2)This->d3d;
609 /*** DrawPrimitive API ***/
610 static HRESULT WINAPI IDirect3DDevice2Impl_SetCurrentViewport(LPDIRECT3DDEVICE2 iface,
611 LPDIRECT3DVIEWPORT2 lpvp)
613 ICOM_THIS(IDirect3DDevice2Impl,iface);
614 IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
615 FIXME("(%p)->(%p): stub\n", This, ilpvp);
617 /* Should check if the viewport was added or not */
619 /* Set this viewport as the current viewport */
620 This->current_viewport = ilpvp;
622 /* Activate this viewport */
623 ilpvp->device.active_device2 = This;
624 ilpvp->activate(ilpvp);
631 static HRESULT WINAPI IDirect3DDevice2Impl_GetCurrentViewport(LPDIRECT3DDEVICE2 iface,
632 LPDIRECT3DVIEWPORT2 *lplpvp)
634 ICOM_THIS(IDirect3DDevice2Impl,iface);
635 FIXME("(%p)->(%p): stub\n", This, lplpvp);
637 /* Returns the current viewport */
638 *lplpvp = (LPDIRECT3DVIEWPORT2)This->current_viewport;
645 static HRESULT WINAPI IDirect3DDevice2Impl_SetRenderTarget(LPDIRECT3DDEVICE2 iface,
646 LPDIRECTDRAWSURFACE lpdds,
649 ICOM_THIS(IDirect3DDevice2Impl,iface);
650 FIXME("(%p)->(%p,%08lx): stub\n", This, lpdds, dwFlags);
657 static HRESULT WINAPI IDirect3DDevice2Impl_GetRenderTarget(LPDIRECT3DDEVICE2 iface,
658 LPDIRECTDRAWSURFACE *lplpdds)
660 ICOM_THIS(IDirect3DDevice2Impl,iface);
661 FIXME("(%p)->(%p): stub\n", This, lplpdds);
663 /* Returns the current rendering target (the surface on wich we render) */
664 *lplpdds = (LPDIRECTDRAWSURFACE)This->surface;
671 static HRESULT WINAPI IDirect3DDevice2Impl_Begin(LPDIRECT3DDEVICE2 iface,
672 D3DPRIMITIVETYPE d3dp,
676 ICOM_THIS(IDirect3DDevice2Impl,iface);
677 FIXME("(%p)->(%d,%d,%08lx): stub\n", This, d3dp, d3dv, dwFlags);
684 static HRESULT WINAPI IDirect3DDevice2Impl_BeginIndexed(LPDIRECT3DDEVICE2 iface,
685 D3DPRIMITIVETYPE d3dp,
691 ICOM_THIS(IDirect3DDevice2Impl,iface);
692 FIXME("(%p)->(%d,%d,%p,%ld,%08lx): stub\n", This, d3dp, d3dv, lpvert, numvert, dwFlags);
699 static HRESULT WINAPI IDirect3DDevice2Impl_Vertex(LPDIRECT3DDEVICE2 iface,
702 ICOM_THIS(IDirect3DDevice2Impl,iface);
703 FIXME("(%p)->(%p): stub\n", This, lpvert);
710 static HRESULT WINAPI IDirect3DDevice2Impl_Index(LPDIRECT3DDEVICE2 iface,
713 ICOM_THIS(IDirect3DDevice2Impl,iface);
714 FIXME("(%p)->(%d): stub\n", This, index);
721 static HRESULT WINAPI IDirect3DDevice2Impl_End(LPDIRECT3DDEVICE2 iface,
724 ICOM_THIS(IDirect3DDevice2Impl,iface);
725 FIXME("(%p)->(%08lx): stub\n", This, dwFlags);
733 static HRESULT WINAPI IDirect3DDevice2Impl_GetRenderState(LPDIRECT3DDEVICE2 iface,
734 D3DRENDERSTATETYPE d3drs,
737 ICOM_THIS(IDirect3DDevice2Impl,iface);
738 FIXME("(%p)->(%d,%p): stub\n", This, d3drs, lprstate);
745 static HRESULT WINAPI IDirect3DDevice2Impl_SetRenderState(LPDIRECT3DDEVICE2 iface,
746 D3DRENDERSTATETYPE dwRenderStateType,
749 ICOM_THIS(IDirect3DDevice2Impl,iface);
750 OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) This;
752 TRACE("(%p)->(%d,%ld)\n", This, dwRenderStateType, dwRenderState);
754 /* Call the render state functions */
755 set_render_state(dwRenderStateType, dwRenderState, &(odev->rs));
762 static HRESULT WINAPI IDirect3DDevice2Impl_GetLightState(LPDIRECT3DDEVICE2 iface,
763 D3DLIGHTSTATETYPE d3dls,
766 ICOM_THIS(IDirect3DDevice2Impl,iface);
767 FIXME("(%p)->(%d,%p): stub\n", This, d3dls, lplstate);
774 static HRESULT WINAPI IDirect3DDevice2Impl_SetLightState(LPDIRECT3DDEVICE2 iface,
775 D3DLIGHTSTATETYPE dwLightStateType,
778 ICOM_THIS(IDirect3DDevice2Impl,iface);
779 FIXME("(%p)->(%d,%08lx): stub\n", This, dwLightStateType, dwLightState);
781 switch (dwLightStateType) {
782 case D3DLIGHTSTATE_MATERIAL: { /* 1 */
783 IDirect3DMaterial2Impl* mat = (IDirect3DMaterial2Impl*) dwLightState;
790 TRACE("Zoups !!!\n");
794 case D3DLIGHTSTATE_AMBIENT: { /* 2 */
797 light[0] = ((dwLightState >> 16) & 0xFF) / 255.0;
798 light[1] = ((dwLightState >> 8) & 0xFF) / 255.0;
799 light[2] = ((dwLightState >> 0) & 0xFF) / 255.0;
802 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (float *) light);
806 case D3DLIGHTSTATE_COLORMODEL: /* 3 */
809 case D3DLIGHTSTATE_FOGMODE: /* 4 */
812 case D3DLIGHTSTATE_FOGSTART: /* 5 */
815 case D3DLIGHTSTATE_FOGEND: /* 6 */
818 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */
822 TRACE("Unexpected Light State Type\n");
823 return DDERR_INVALIDPARAMS;
831 static HRESULT WINAPI IDirect3DDevice2Impl_SetTransform(LPDIRECT3DDEVICE2 iface,
832 D3DTRANSFORMSTATETYPE d3dts,
833 LPD3DMATRIX lpmatrix)
835 ICOM_THIS(IDirect3DDevice2Impl,iface);
836 OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) This;
838 FIXME("(%p)->(%d,%p): stub\n", This, d3dts, lpmatrix);
842 /* Using a trial and failure approach, I found that the order of
843 Direct3D transformations that works best is :
845 ScreenCoord = ProjectionMat * ViewMat * WorldMat * ObjectCoord
847 As OpenGL uses only two matrices, I combined PROJECTION and VIEW into
848 OpenGL's GL_PROJECTION matrix and the WORLD into GL_MODELVIEW.
850 If anyone has a good explanation of the three different matrices in
851 the SDK online documentation, feel free to point it to me. For example,
852 which matrices transform lights ? In OpenGL only the PROJECTION matrix
853 transform the lights, not the MODELVIEW. Using the matrix names, I
854 supposed that PROJECTION and VIEW (all 'camera' related names) do
855 transform lights, but WORLD do not. It may be wrong though... */
857 /* After reading through both OpenGL and Direct3D documentations, I
858 thought that D3D matrices were written in 'line major mode' transposed
859 from OpenGL's 'column major mode'. But I found out that a simple memcpy
860 works fine to transfer one matrix format to the other (it did not work
861 when transposing)....
864 1) are the documentations wrong
865 2) does the matrix work even if they are not read correctly
866 3) is Mesa's implementation of OpenGL not compliant regarding Matrix
867 loading using glLoadMatrix ?
869 Anyway, I always use 'conv_mat' to transfer the matrices from one format
870 to the other so that if I ever find out that I need to transpose them, I
871 will able to do it quickly, only by changing the macro conv_mat. */
874 case D3DTRANSFORMSTATE_WORLD: {
875 conv_mat(lpmatrix, odev->world_mat);
876 glMatrixMode(GL_MODELVIEW);
877 glLoadMatrixf((float *) &(odev->world_mat));
880 case D3DTRANSFORMSTATE_VIEW: {
881 conv_mat(lpmatrix, odev->view_mat);
882 glMatrixMode(GL_PROJECTION);
883 glLoadMatrixf((float *) &(odev->proj_mat));
884 glMultMatrixf((float *) &(odev->view_mat));
887 case D3DTRANSFORMSTATE_PROJECTION: {
888 conv_mat(lpmatrix, odev->proj_mat);
889 glMatrixMode(GL_PROJECTION);
890 glLoadMatrixf((float *) &(odev->proj_mat));
891 glMultMatrixf((float *) &(odev->view_mat));
905 static HRESULT WINAPI IDirect3DDevice2Impl_GetTransform(LPDIRECT3DDEVICE2 iface,
906 D3DTRANSFORMSTATETYPE d3dts,
907 LPD3DMATRIX lpmatrix)
909 ICOM_THIS(IDirect3DDevice2Impl,iface);
910 FIXME("(%p)->(%d,%p): stub\n", This, d3dts, lpmatrix);
917 static HRESULT WINAPI IDirect3DDevice2Impl_MultiplyTransform(LPDIRECT3DDEVICE2 iface,
918 D3DTRANSFORMSTATETYPE d3dts,
919 LPD3DMATRIX lpmatrix)
921 ICOM_THIS(IDirect3DDevice2Impl,iface);
922 FIXME("(%p)->(%d,%p): stub\n", This, d3dts, lpmatrix);
927 #define DRAW_PRIMITIVE(MAXVERT,INDEX) \
928 /* Puts GL in the correct lighting mode */ \
929 if (odev->vt != d3dv) { \
930 if (odev->vt == D3DVT_TLVERTEX) { \
931 /* Need to put the correct transformation again */ \
932 glMatrixMode(GL_MODELVIEW); \
933 glLoadMatrixf((float *) &(odev->world_mat)); \
934 glMatrixMode(GL_PROJECTION); \
935 glLoadMatrixf((float *) &(odev->proj_mat)); \
936 glMultMatrixf((float *) &(odev->view_mat)); \
941 TRACE("Standard Vertex\n"); \
942 glEnable(GL_LIGHTING); \
945 case D3DVT_LVERTEX: \
946 TRACE("Lighted Vertex\n"); \
947 glDisable(GL_LIGHTING); \
950 case D3DVT_TLVERTEX: { \
951 GLdouble height, width, minZ, maxZ; \
953 TRACE("Transformed - Lighted Vertex\n"); \
954 /* First, disable lighting */ \
955 glDisable(GL_LIGHTING); \
957 /* Then do not put any transformation matrixes */ \
958 glMatrixMode(GL_MODELVIEW); \
960 glMatrixMode(GL_PROJECTION); \
963 if (This->current_viewport == NULL) { \
964 ERR("No current viewport !\n"); \
965 /* Using standard values */ \
971 if (This->current_viewport->use_vp2) { \
972 height = (GLdouble) This->current_viewport->viewport.vp2.dwHeight; \
973 width = (GLdouble) This->current_viewport->viewport.vp2.dwWidth; \
974 minZ = (GLdouble) This->current_viewport->viewport.vp2.dvMinZ; \
975 maxZ = (GLdouble) This->current_viewport->viewport.vp2.dvMaxZ; \
977 height = (GLdouble) This->current_viewport->viewport.vp1.dwHeight; \
978 width = (GLdouble) This->current_viewport->viewport.vp1.dwWidth; \
979 minZ = (GLdouble) This->current_viewport->viewport.vp1.dvMinZ; \
980 maxZ = (GLdouble) This->current_viewport->viewport.vp1.dvMaxZ; \
984 glOrtho(0.0, width, height, 0.0, -minZ, -maxZ); \
988 ERR("Unhandled vertex type\n"); \
996 case D3DPT_POINTLIST: \
997 TRACE("Start POINTS\n"); \
998 glBegin(GL_POINTS); \
1001 case D3DPT_LINELIST: \
1002 TRACE("Start LINES\n"); \
1003 glBegin(GL_LINES); \
1006 case D3DPT_LINESTRIP: \
1007 TRACE("Start LINE_STRIP\n"); \
1008 glBegin(GL_LINE_STRIP); \
1011 case D3DPT_TRIANGLELIST: \
1012 TRACE("Start TRIANGLES\n"); \
1013 glBegin(GL_TRIANGLES); \
1016 case D3DPT_TRIANGLESTRIP: \
1017 TRACE("Start TRIANGLE_STRIP\n"); \
1018 glBegin(GL_TRIANGLE_STRIP); \
1021 case D3DPT_TRIANGLEFAN: \
1022 TRACE("Start TRIANGLE_FAN\n"); \
1023 glBegin(GL_TRIANGLE_FAN); \
1027 TRACE("Unhandled primitive\n"); \
1031 /* Draw the primitives */ \
1032 for (vx_index = 0; vx_index < MAXVERT; vx_index++) { \
1034 case D3DVT_VERTEX: { \
1035 D3DVERTEX *vx = ((D3DVERTEX *) lpvertex) + INDEX; \
1037 glNormal3f(vx->nx.nx, vx->ny.ny, vx->nz.nz); \
1038 glVertex3f(vx->x.x, vx->y.y, vx->z.z); \
1039 TRACE(" V: %f %f %f\n", vx->x.x, vx->y.y, vx->z.z); \
1042 case D3DVT_LVERTEX: { \
1043 D3DLVERTEX *vx = ((D3DLVERTEX *) lpvertex) + INDEX; \
1044 DWORD col = vx->c.color; \
1046 glColor3f(((col >> 16) & 0xFF) / 255.0, \
1047 ((col >> 8) & 0xFF) / 255.0, \
1048 ((col >> 0) & 0xFF) / 255.0); \
1049 glVertex3f(vx->x.x, vx->y.y, vx->z.z); \
1050 TRACE(" LV: %f %f %f (%02lx %02lx %02lx)\n", \
1051 vx->x.x, vx->y.y, vx->z.z, \
1052 ((col >> 16) & 0xFF), ((col >> 8) & 0xFF), ((col >> 0) & 0xFF)); \
1055 case D3DVT_TLVERTEX: { \
1056 D3DTLVERTEX *vx = ((D3DTLVERTEX *) lpvertex) + INDEX; \
1057 DWORD col = vx->c.color; \
1059 glColor3f(((col >> 16) & 0xFF) / 255.0, \
1060 ((col >> 8) & 0xFF) / 255.0, \
1061 ((col >> 0) & 0xFF) / 255.0); \
1062 glTexCoord2f(vx->u.tu, vx->v.tv); \
1063 if (vx->r.rhw < 0.01) \
1064 glVertex3f(vx->x.sx, \
1068 glVertex4f(vx->x.sx / vx->r.rhw, \
1069 vx->y.sy / vx->r.rhw, \
1070 vx->z.sz / vx->r.rhw, \
1072 TRACE(" TLV: %f %f %f (%02lx %02lx %02lx) (%f %f) (%f)\n", \
1073 vx->x.sx, vx->y.sy, vx->z.sz, \
1074 ((col >> 16) & 0xFF), ((col >> 8) & 0xFF), ((col >> 0) & 0xFF), \
1075 vx->u.tu, vx->v.tv, vx->r.rhw); \
1079 TRACE("Unhandled vertex type\n"); \
1088 static HRESULT WINAPI IDirect3DDevice2Impl_DrawPrimitive(LPDIRECT3DDEVICE2 iface,
1089 D3DPRIMITIVETYPE d3dp,
1095 ICOM_THIS(IDirect3DDevice2Impl,iface);
1096 OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) This;
1099 TRACE("(%p)->(%d,%d,%p,%ld,%08lx): stub\n", This, d3dp, d3dv, lpvertex, vertcount, dwFlags);
1102 DRAW_PRIMITIVE(vertcount, vx_index);
1110 static HRESULT WINAPI IDirect3DDevice2Impl_DrawIndexedPrimitive(LPDIRECT3DDEVICE2 iface,
1111 D3DPRIMITIVETYPE d3dp,
1119 ICOM_THIS(IDirect3DDevice2Impl,iface);
1120 OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) This;
1123 TRACE("(%p)->(%d,%d,%p,%ld,%p,%ld,%08lx): stub\n", This, d3dp, d3dv, lpvertex, vertcount, lpindexes, indexcount, dwFlags);
1126 DRAW_PRIMITIVE(indexcount, lpindexes[vx_index]);
1134 static HRESULT WINAPI IDirect3DDevice2Impl_SetClipStatus(LPDIRECT3DDEVICE2 iface,
1135 LPD3DCLIPSTATUS lpcs)
1137 ICOM_THIS(IDirect3DDevice2Impl,iface);
1138 FIXME("(%p)->(%p): stub\n", This, lpcs);
1145 static HRESULT WINAPI IDirect3DDevice2Impl_GetClipStatus(LPDIRECT3DDEVICE2 iface,
1146 LPD3DCLIPSTATUS lpcs)
1148 ICOM_THIS(IDirect3DDevice2Impl,iface);
1149 FIXME("(%p)->(%p): stub\n", This, lpcs);
1156 /*******************************************************************************
1157 * OpenGL-specific IDirect3DDevice2
1160 /*******************************************************************************
1161 * OpenGL-specific VTable
1164 static ICOM_VTABLE(IDirect3DDevice2) OpenGL_vtable =
1166 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1167 IDirect3DDevice2Impl_QueryInterface,
1168 IDirect3DDevice2Impl_AddRef,
1169 IDirect3DDevice2Impl_Release,
1170 /*** IDirect3DDevice2 methods ***/
1171 IDirect3DDevice2Impl_GetCaps,
1172 IDirect3DDevice2Impl_SwapTextureHandles,
1173 IDirect3DDevice2Impl_GetStats,
1174 IDirect3DDevice2Impl_AddViewport,
1175 IDirect3DDevice2Impl_DeleteViewport,
1176 IDirect3DDevice2Impl_NextViewport,
1177 IDirect3DDevice2Impl_EnumTextureFormats,
1178 IDirect3DDevice2Impl_BeginScene,
1179 IDirect3DDevice2Impl_EndScene,
1180 IDirect3DDevice2Impl_GetDirect3D,
1182 /*** DrawPrimitive API ***/
1183 IDirect3DDevice2Impl_SetCurrentViewport,
1184 IDirect3DDevice2Impl_GetCurrentViewport,
1186 IDirect3DDevice2Impl_SetRenderTarget,
1187 IDirect3DDevice2Impl_GetRenderTarget,
1189 IDirect3DDevice2Impl_Begin,
1190 IDirect3DDevice2Impl_BeginIndexed,
1191 IDirect3DDevice2Impl_Vertex,
1192 IDirect3DDevice2Impl_Index,
1193 IDirect3DDevice2Impl_End,
1195 IDirect3DDevice2Impl_GetRenderState,
1196 IDirect3DDevice2Impl_SetRenderState,
1197 IDirect3DDevice2Impl_GetLightState,
1198 IDirect3DDevice2Impl_SetLightState,
1199 IDirect3DDevice2Impl_SetTransform,
1200 IDirect3DDevice2Impl_GetTransform,
1201 IDirect3DDevice2Impl_MultiplyTransform,
1203 IDirect3DDevice2Impl_DrawPrimitive,
1204 IDirect3DDevice2Impl_DrawIndexedPrimitive,
1206 IDirect3DDevice2Impl_SetClipStatus,
1207 IDirect3DDevice2Impl_GetClipStatus,
1210 /*******************************************************************************
1213 int d3d_OpenGL_dx3(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) {
1214 D3DDEVICEDESC d1,d2;
1216 TRACE(" Enumerating OpenGL D3D device.\n");
1218 fill_opengl_caps(&d1, &d2);
1220 return cb((void*)&IID_D3DDEVICE_OpenGL,"WINE Direct3D using OpenGL","direct3d",&d1,&d2,context);
1223 float id_mat[16] = {
1230 int is_OpenGL_dx3(REFCLSID rguid, IDirectDrawSurfaceImpl* surface, IDirect3DDeviceImpl** device)
1232 if (!memcmp(&IID_D3DDEVICE_OpenGL,rguid,sizeof(IID_D3DDEVICE_OpenGL))) {
1233 OpenGL_IDirect3DDevice *odev;
1235 int attributeList[]={ GLX_RGBA, GLX_DEPTH_SIZE, 16, GLX_DOUBLEBUFFER, None };
1239 *device = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(OpenGL_IDirect3DDevice));
1240 odev = (OpenGL_IDirect3DDevice *) (*device);
1242 (*device)->lpvtbl = &OpenGL_vtable_dx3;
1243 (*device)->d3d = NULL;
1244 (*device)->surface = surface;
1246 (*device)->viewport_list = NULL;
1247 (*device)->current_viewport = NULL;
1249 (*device)->set_context = set_context_dx3;
1251 TRACE("OpenGL device created \n");
1253 /* Create the OpenGL context */
1255 odev->ctx = OSMesaCreateContext(OSMESA_RGBA, NULL);
1256 odev->buffer = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
1257 surface->s.surface_desc.dwWidth * surface->s.surface_desc.dwHeight * 4);
1259 /* First get the correct visual */
1260 /* if (surface->s.backbuffer == NULL)
1261 attributeList[3] = None; */
1263 xvis = glXChooseVisual(display,
1264 DefaultScreen(display),
1267 ERR("No visual found !\n");
1269 TRACE("Visual found\n");
1270 /* Create the context */
1271 odev->ctx = glXCreateContext(display,
1275 TRACE("Context created\n");
1277 /* Now override the surface's Flip method (if in double buffering) */
1278 surface->s.d3d_device = (void *) odev;
1281 struct _surface_chain *chain = surface->s.chain;
1282 for (i=0;i<chain->nrofsurfaces;i++)
1283 if (chain->surfaces[i]->s.surface_desc.ddsCaps.dwCaps & DDSCAPS_FLIP)
1284 chain->surfaces[i]->s.d3d_device = (void *) odev;
1287 odev->rs.src = GL_ONE;
1288 odev->rs.dst = GL_ZERO;
1289 odev->rs.mag = GL_NEAREST;
1290 odev->rs.min = GL_NEAREST;
1292 odev->world_mat = (LPD3DMATRIX) &id_mat;
1293 odev->view_mat = (LPD3DMATRIX) &id_mat;
1294 odev->proj_mat = (LPD3DMATRIX) &id_mat;
1296 /* Initialisation */
1297 (*device)->set_context(*device);
1298 glClearColor(0.0, 0.0, 0.0, 0.0);
1299 glColor3f(1.0, 1.0, 1.0);
1304 /* This is not the OpenGL UID */
1309 /*******************************************************************************
1312 static HRESULT WINAPI IDirect3DDeviceImpl_QueryInterface(LPDIRECT3DDEVICE iface,
1316 ICOM_THIS(IDirect3DDeviceImpl,iface);
1319 WINE_StringFromCLSID((LPCLSID)riid,xrefiid);
1320 FIXME("(%p)->(%s,%p): stub\n", This, xrefiid,ppvObj);
1327 static ULONG WINAPI IDirect3DDeviceImpl_AddRef(LPDIRECT3DDEVICE iface)
1329 ICOM_THIS(IDirect3DDeviceImpl,iface);
1330 TRACE("(%p)->()incrementing from %lu.\n", This, This->ref );
1332 return ++(This->ref);
1337 static ULONG WINAPI IDirect3DDeviceImpl_Release(LPDIRECT3DDEVICE iface)
1339 ICOM_THIS(IDirect3DDeviceImpl,iface);
1340 FIXME("(%p)->() decrementing from %lu.\n", This, This->ref );
1342 if (!--(This->ref)) {
1343 OpenGL_IDirect3DDevice *odev = (OpenGL_IDirect3DDevice *) This;
1346 OSMesaDestroyContext(odev->ctx);
1349 glXDestroyContext(display,
1354 HeapFree(GetProcessHeap(),0,This);
1361 static HRESULT WINAPI IDirect3DDeviceImpl_Initialize(LPDIRECT3DDEVICE iface,
1364 LPD3DDEVICEDESC lpd3ddvdesc)
1366 ICOM_THIS(IDirect3DDeviceImpl,iface);
1367 TRACE("(%p)->(%p,%p,%p): stub\n", This, lpd3d,lpGUID, lpd3ddvdesc);
1369 return DDERR_ALREADYINITIALIZED;
1373 static HRESULT WINAPI IDirect3DDeviceImpl_GetCaps(LPDIRECT3DDEVICE iface,
1374 LPD3DDEVICEDESC lpD3DHWDevDesc,
1375 LPD3DDEVICEDESC lpD3DSWDevDesc)
1377 ICOM_THIS(IDirect3DDeviceImpl,iface);
1378 TRACE("(%p)->(%p,%p): stub\n", This, lpD3DHWDevDesc, lpD3DSWDevDesc);
1380 fill_opengl_caps(lpD3DHWDevDesc, lpD3DSWDevDesc);
1386 static HRESULT WINAPI IDirect3DDeviceImpl_SwapTextureHandles(LPDIRECT3DDEVICE iface,
1387 LPDIRECT3DTEXTURE lpD3DTex1,
1388 LPDIRECT3DTEXTURE lpD3DTex2)
1390 ICOM_THIS(IDirect3DDeviceImpl,iface);
1391 TRACE("(%p)->(%p,%p): stub\n", This, lpD3DTex1, lpD3DTex2);
1396 static HRESULT WINAPI IDirect3DDeviceImpl_CreateExecuteBuffer(LPDIRECT3DDEVICE iface,
1397 LPD3DEXECUTEBUFFERDESC lpDesc,
1398 LPDIRECT3DEXECUTEBUFFER *lplpDirect3DExecuteBuffer,
1399 IUnknown *pUnkOuter)
1401 ICOM_THIS(IDirect3DDeviceImpl,iface);
1402 TRACE("(%p)->(%p,%p,%p)\n", This, lpDesc, lplpDirect3DExecuteBuffer, pUnkOuter);
1404 *lplpDirect3DExecuteBuffer = d3dexecutebuffer_create(This, lpDesc);
1410 static HRESULT WINAPI IDirect3DDeviceImpl_GetStats(LPDIRECT3DDEVICE iface,
1411 LPD3DSTATS lpD3DStats)
1413 ICOM_THIS(IDirect3DDeviceImpl,iface);
1414 TRACE("(%p)->(%p): stub\n", This, lpD3DStats);
1420 static HRESULT WINAPI IDirect3DDeviceImpl_Execute(LPDIRECT3DDEVICE iface,
1421 LPDIRECT3DEXECUTEBUFFER lpDirect3DExecuteBuffer,
1422 LPDIRECT3DVIEWPORT lpDirect3DViewport,
1425 ICOM_THIS(IDirect3DDeviceImpl,iface);
1426 TRACE("(%p)->(%p,%p,%08ld): stub\n", This, lpDirect3DExecuteBuffer, lpDirect3DViewport, dwFlags);
1428 /* Put this as the default context */
1431 ((IDirect3DExecuteBufferImpl*)lpDirect3DExecuteBuffer)->execute(lpDirect3DExecuteBuffer, iface, lpDirect3DViewport);
1436 static HRESULT WINAPI IDirect3DDeviceImpl_AddViewport(LPDIRECT3DDEVICE iface,
1437 LPDIRECT3DVIEWPORT lpvp)
1439 ICOM_THIS(IDirect3DDeviceImpl,iface);
1440 IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
1441 FIXME("(%p)->(%p): stub\n", This, ilpvp);
1443 /* Adds this viewport to the viewport list */
1444 ilpvp->next = This->viewport_list;
1445 This->viewport_list = ilpvp;
1452 static HRESULT WINAPI IDirect3DDeviceImpl_DeleteViewport(LPDIRECT3DDEVICE iface,
1453 LPDIRECT3DVIEWPORT lpvp)
1455 ICOM_THIS(IDirect3DDeviceImpl,iface);
1456 IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
1457 IDirect3DViewport2Impl *cur, *prev;
1458 FIXME("(%p)->(%p): stub\n", This, lpvp);
1460 /* Finds this viewport in the list */
1462 cur = This->viewport_list;
1463 while ((cur != NULL) && (cur != ilpvp)) {
1468 return DDERR_INVALIDOBJECT;
1472 This->viewport_list = cur->next;
1474 prev->next = cur->next;
1481 static HRESULT WINAPI IDirect3DDeviceImpl_NextViewport(LPDIRECT3DDEVICE iface,
1482 LPDIRECT3DVIEWPORT lpvp,
1483 LPDIRECT3DVIEWPORT* lplpvp,
1486 ICOM_THIS(IDirect3DDeviceImpl,iface);
1487 IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
1488 IDirect3DViewport2Impl** ilplpvp=(IDirect3DViewport2Impl**)lplpvp;
1489 FIXME("(%p)->(%p,%p,%08lx): stub\n", This, ilpvp, ilplpvp, dwFlags);
1493 *ilplpvp = ilpvp->next;
1497 *ilplpvp = This->viewport_list;
1501 ilpvp = This->viewport_list;
1502 while (ilpvp->next != NULL)
1503 ilpvp = ilpvp->next;
1509 return DDERR_INVALIDPARAMS;
1515 static HRESULT WINAPI IDirect3DDeviceImpl_Pick(LPDIRECT3DDEVICE iface,
1516 LPDIRECT3DEXECUTEBUFFER lpDirect3DExecuteBuffer,
1517 LPDIRECT3DVIEWPORT lpDirect3DViewport,
1521 ICOM_THIS(IDirect3DDeviceImpl,iface);
1522 TRACE("(%p)->(%p,%p,%08lx,%p): stub\n", This, lpDirect3DExecuteBuffer, lpDirect3DViewport,
1529 static HRESULT WINAPI IDirect3DDeviceImpl_GetPickRecords(LPDIRECT3DDEVICE iface,
1531 LPD3DPICKRECORD lpD3DPickRec)
1533 ICOM_THIS(IDirect3DDeviceImpl,iface);
1534 TRACE("(%p)->(%p,%p): stub\n", This, lpCount, lpD3DPickRec);
1540 static HRESULT WINAPI IDirect3DDeviceImpl_EnumTextureFormats(LPDIRECT3DDEVICE iface,
1541 LPD3DENUMTEXTUREFORMATSCALLBACK lpd3dEnumTextureProc,
1544 ICOM_THIS(IDirect3DDeviceImpl,iface);
1545 TRACE("(%p)->(%p,%p): stub\n", This, lpd3dEnumTextureProc, lpArg);
1547 return enum_texture_format_OpenGL(lpd3dEnumTextureProc, lpArg);
1551 static HRESULT WINAPI IDirect3DDeviceImpl_CreateMatrix(LPDIRECT3DDEVICE iface,
1552 LPD3DMATRIXHANDLE lpD3DMatHandle)
1554 ICOM_THIS(IDirect3DDeviceImpl,iface);
1555 TRACE("(%p)->(%p)\n", This, lpD3DMatHandle);
1557 *lpD3DMatHandle = (D3DMATRIXHANDLE) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(D3DMATRIX));
1563 static HRESULT WINAPI IDirect3DDeviceImpl_SetMatrix(LPDIRECT3DDEVICE iface,
1564 D3DMATRIXHANDLE d3dMatHandle,
1565 const LPD3DMATRIX lpD3DMatrix)
1567 ICOM_THIS(IDirect3DDeviceImpl,iface);
1568 TRACE("(%p)->(%08lx,%p)\n", This, d3dMatHandle, lpD3DMatrix);
1570 dump_mat(lpD3DMatrix);
1572 *((D3DMATRIX *) d3dMatHandle) = *lpD3DMatrix;
1578 static HRESULT WINAPI IDirect3DDeviceImpl_GetMatrix(LPDIRECT3DDEVICE iface,
1579 D3DMATRIXHANDLE D3DMatHandle,
1580 LPD3DMATRIX lpD3DMatrix)
1582 ICOM_THIS(IDirect3DDeviceImpl,iface);
1583 TRACE("(%p)->(%08lx,%p)\n", This, D3DMatHandle, lpD3DMatrix);
1585 *lpD3DMatrix = *((D3DMATRIX *) D3DMatHandle);
1591 static HRESULT WINAPI IDirect3DDeviceImpl_DeleteMatrix(LPDIRECT3DDEVICE iface,
1592 D3DMATRIXHANDLE d3dMatHandle)
1594 ICOM_THIS(IDirect3DDeviceImpl,iface);
1595 TRACE("(%p)->(%08lx)\n", This, d3dMatHandle);
1597 HeapFree(GetProcessHeap(),0, (void *) d3dMatHandle);
1603 static HRESULT WINAPI IDirect3DDeviceImpl_BeginScene(LPDIRECT3DDEVICE iface)
1605 ICOM_THIS(IDirect3DDeviceImpl,iface);
1606 /* OpenGL_IDirect3DDevice *odev = (OpenGL_IDirect3DDevice *) This; */
1608 FIXME("(%p)->(): stub\n", This);
1610 /* We get the pointer to the surface (should be done on flip) */
1611 /* odev->zb->pbuf = This->surface->s.surface_desc.y.lpSurface; */
1617 /* This is for the moment copy-pasted from IDirect3DDevice2...
1618 Will make a common function ... */
1619 static HRESULT WINAPI IDirect3DDeviceImpl_EndScene(LPDIRECT3DDEVICE iface)
1621 ICOM_THIS(IDirect3DDeviceImpl,iface);
1623 OpenGL_IDirect3DDevice *odev = (OpenGL_IDirect3DDevice *) This;
1624 LPDIRECTDRAWSURFACE3 surf = (LPDIRECTDRAWSURFACE3) This->surface;
1625 DDSURFACEDESC sdesc;
1628 unsigned short *dest;
1631 FIXME("(%p)->(): stub\n", This);
1634 /* Here we copy back the OpenGL scene to the the DDraw surface */
1635 /* First, lock the surface */
1636 IDirectDrawSurface3_Lock(surf,NULL,&sdesc,DDLOCK_WRITEONLY,0);
1638 /* The copy the OpenGL buffer to this surface */
1640 /* NOTE : this is only for debugging purpose. I KNOW it is really unoptimal.
1641 I am currently working on a set of patches for Mesa to have OSMesa support
1642 16 bpp surfaces => we will able to render directly onto the surface, no
1643 need to do a bpp conversion */
1644 dest = (unsigned short *) sdesc.y.lpSurface;
1645 src = ((unsigned char *) odev->buffer) + 4 * (sdesc.dwWidth * (sdesc.dwHeight - 1));
1646 for (y = 0; y < sdesc.dwHeight; y++) {
1647 unsigned char *lsrc = src;
1649 for (x = 0; x < sdesc.dwWidth ; x++) {
1650 unsigned char r = *lsrc++;
1651 unsigned char g = *lsrc++;
1652 unsigned char b = *lsrc++;
1655 *dest = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
1660 src -= 4 * sdesc.dwWidth;
1663 /* Unlock the surface */
1664 IDirectDrawSurface3_Unlock(surf,sdesc.y.lpSurface);
1666 /* No need to do anything here... */
1673 static HRESULT WINAPI IDirect3DDeviceImpl_GetDirect3D(LPDIRECT3DDEVICE iface,
1674 LPDIRECT3D *lpDirect3D)
1676 ICOM_THIS(IDirect3DDeviceImpl,iface);
1677 TRACE("(%p)->(%p): stub\n", This, lpDirect3D);
1684 /*******************************************************************************
1685 * Direct3DDevice VTable
1687 static ICOM_VTABLE(IDirect3DDevice) OpenGL_vtable_dx3 =
1689 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1690 IDirect3DDeviceImpl_QueryInterface,
1691 IDirect3DDeviceImpl_AddRef,
1692 IDirect3DDeviceImpl_Release,
1693 IDirect3DDeviceImpl_Initialize,
1694 IDirect3DDeviceImpl_GetCaps,
1695 IDirect3DDeviceImpl_SwapTextureHandles,
1696 IDirect3DDeviceImpl_CreateExecuteBuffer,
1697 IDirect3DDeviceImpl_GetStats,
1698 IDirect3DDeviceImpl_Execute,
1699 IDirect3DDeviceImpl_AddViewport,
1700 IDirect3DDeviceImpl_DeleteViewport,
1701 IDirect3DDeviceImpl_NextViewport,
1702 IDirect3DDeviceImpl_Pick,
1703 IDirect3DDeviceImpl_GetPickRecords,
1704 IDirect3DDeviceImpl_EnumTextureFormats,
1705 IDirect3DDeviceImpl_CreateMatrix,
1706 IDirect3DDeviceImpl_SetMatrix,
1707 IDirect3DDeviceImpl_GetMatrix,
1708 IDirect3DDeviceImpl_DeleteMatrix,
1709 IDirect3DDeviceImpl_BeginScene,
1710 IDirect3DDeviceImpl_EndScene,
1711 IDirect3DDeviceImpl_GetDirect3D,
1714 #else /* HAVE_MESAGL */
1716 int d3d_OpenGL(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) {
1720 int is_OpenGL(REFCLSID rguid, IDirectDrawSurfaceImpl* surface, IDirect3DDevice2Impl** device, IDirect3D2Impl* d3d)
1725 int d3d_OpenGL_dx3(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) {
1729 int is_OpenGL_dx3(REFCLSID rguid, IDirectDrawSurfaceImpl* surface, IDirect3DDeviceImpl** device)
1734 #endif /* HAVE_MESAGL */