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"
18 #include "d3d_private.h"
20 /* Define this variable if you have an unpatched Mesa 3.0 (patches are available
21 on Mesa's home page) or version 3.1b.
23 Version 3.2b should correct this bug */
24 #undef HAVE_BUGGY_MESAGL
28 static GUID IID_D3DDEVICE2_OpenGL = {
32 { 0x8b,0x7c,0x0e,0x4e,0xd8,0x3c,0x2b,0x3c }
35 static GUID IID_D3DDEVICE_OpenGL = {
39 { 0x82,0x2d,0xa8,0xd5,0x31,0x87,0xca,0xfa }
43 static IDirect3DDevice2_VTable OpenGL_vtable;
44 static IDirect3DDevice_VTable OpenGL_vtable_dx3;
46 /*******************************************************************************
47 * OpenGL static functions
49 static void set_context(LPDIRECT3DDEVICE2 this) {
50 OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) this;
52 OSMesaMakeCurrent(odev->ctx, odev->buffer,
54 this->surface->s.surface_desc.dwWidth,
55 this->surface->s.surface_desc.dwHeight);
58 static void set_context_dx3(LPDIRECT3DDEVICE this) {
59 OpenGL_IDirect3DDevice *odev = (OpenGL_IDirect3DDevice *) this;
61 OSMesaMakeCurrent(odev->ctx, odev->buffer,
63 this->surface->s.surface_desc.dwWidth,
64 this->surface->s.surface_desc.dwHeight);
67 static void fill_opengl_primcaps(D3DPRIMCAPS *pc)
69 pc->dwSize = sizeof(*pc);
70 pc->dwMiscCaps = D3DPMISCCAPS_CONFORMANT | D3DPMISCCAPS_CULLCCW | D3DPMISCCAPS_CULLCW |
71 D3DPMISCCAPS_LINEPATTERNREP | D3DPMISCCAPS_MASKZ;
72 pc->dwRasterCaps = D3DPRASTERCAPS_DITHER | D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_FOGTABLE |
73 D3DPRASTERCAPS_FOGVERTEX | D3DPRASTERCAPS_STIPPLE | D3DPRASTERCAPS_ZBIAS | D3DPRASTERCAPS_ZTEST;
74 pc->dwZCmpCaps = 0xFFFFFFFF; /* All Z test can be done */
75 pc->dwSrcBlendCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
76 pc->dwDestBlendCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
77 pc->dwAlphaCmpCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
78 pc->dwShadeCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
79 pc->dwTextureCaps = D3DPTEXTURECAPS_ALPHA | D3DPTEXTURECAPS_BORDER | D3DPTEXTURECAPS_PERSPECTIVE |
80 D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_TRANSPARENCY;
81 pc->dwTextureFilterCaps = D3DPTFILTERCAPS_LINEAR | D3DPTFILTERCAPS_LINEARMIPLINEAR | D3DPTFILTERCAPS_LINEARMIPNEAREST |
82 D3DPTFILTERCAPS_MIPLINEAR | D3DPTFILTERCAPS_MIPNEAREST | D3DPTFILTERCAPS_NEAREST;
83 pc->dwTextureBlendCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
84 pc->dwTextureAddressCaps = D3DPTADDRESSCAPS_BORDER | D3DPTADDRESSCAPS_CLAMP | D3DPTADDRESSCAPS_WRAP;
85 pc->dwStippleWidth = 32;
86 pc->dwStippleHeight = 32;
89 static void fill_opengl_caps(D3DDEVICEDESC *d1, D3DDEVICEDESC *d2)
93 d1->dwSize = sizeof(*d1);
94 d1->dwFlags = D3DDD_DEVCAPS | D3DDD_BCLIPPING | D3DDD_COLORMODEL | D3DDD_DEVICERENDERBITDEPTH | D3DDD_DEVICEZBUFFERBITDEPTH
95 | D3DDD_LIGHTINGCAPS | D3DDD_LINECAPS | D3DDD_MAXBUFFERSIZE | D3DDD_MAXVERTEXCOUNT | D3DDD_TRANSFORMCAPS | D3DDD_TRICAPS;
96 d1->dcmColorModel = D3DCOLOR_RGB;
97 d1->dwDevCaps = D3DDEVCAPS_CANRENDERAFTERFLIP | D3DDEVCAPS_DRAWPRIMTLVERTEX | D3DDEVCAPS_EXECUTESYSTEMMEMORY |
98 D3DDEVCAPS_EXECUTEVIDEOMEMORY | D3DDEVCAPS_FLOATTLVERTEX | D3DDEVCAPS_TEXTURENONLOCALVIDMEM | D3DDEVCAPS_TEXTURESYSTEMMEMORY |
99 D3DDEVCAPS_TEXTUREVIDEOMEMORY | D3DDEVCAPS_TLVERTEXSYSTEMMEMORY | D3DDEVCAPS_TLVERTEXVIDEOMEMORY;
100 d1->dtcTransformCaps.dwSize = sizeof(D3DTRANSFORMCAPS);
101 d1->dtcTransformCaps.dwCaps = D3DTRANSFORMCAPS_CLIP;
102 d1->bClipping = TRUE;
103 d1->dlcLightingCaps.dwSize = sizeof(D3DLIGHTINGCAPS);
104 d1->dlcLightingCaps.dwCaps = D3DLIGHTCAPS_DIRECTIONAL | D3DLIGHTCAPS_PARALLELPOINT | D3DLIGHTCAPS_POINT | D3DLIGHTCAPS_SPOT;
105 d1->dlcLightingCaps.dwLightingModel = D3DLIGHTINGMODEL_RGB;
106 d1->dlcLightingCaps.dwNumLights = 16; /* glGetIntegerv(GL_MAX_LIGHTS, &maxlight); d1->dlcLightingCaps.dwNumLights = maxlight; */
107 fill_opengl_primcaps(&(d1->dpcLineCaps));
108 fill_opengl_primcaps(&(d1->dpcTriCaps));
109 d1->dwDeviceRenderBitDepth = DDBD_16;
110 d1->dwDeviceZBufferBitDepth = DDBD_16;
111 d1->dwMaxBufferSize = 0;
112 d1->dwMaxVertexCount = 65536;
113 d1->dwMinTextureWidth = 1;
114 d1->dwMinTextureHeight = 1;
115 d1->dwMaxTextureWidth = 256; /* This is for Mesa on top of Glide (in the future :-) ) */
116 d1->dwMaxTextureHeight = 256; /* This is for Mesa on top of Glide (in the future :-) ) */
117 d1->dwMinStippleWidth = 1;
118 d1->dwMinStippleHeight = 1;
119 d1->dwMaxStippleWidth = 32;
120 d1->dwMaxStippleHeight = 32;
122 d2->dwSize = sizeof(*d2);
126 int d3d_OpenGL(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) {
129 TRACE(ddraw," Enumerating OpenGL D3D device.\n");
131 fill_opengl_caps(&d1, &d2);
133 return cb((void*)&IID_D3DDEVICE2_OpenGL,"WINE Direct3D using OpenGL","direct3d",&d1,&d2,context);
136 int is_OpenGL(REFCLSID rguid, LPDIRECTDRAWSURFACE surface, LPDIRECT3DDEVICE2 *device, LPDIRECT3D2 d3d)
138 if (/* Default device */
141 (!memcmp(&IID_IDirect3DHALDevice,rguid,sizeof(IID_IDirect3DHALDevice))) ||
143 (!memcmp(&IID_D3DDEVICE2_OpenGL,rguid,sizeof(IID_D3DDEVICE2_OpenGL)))) {
144 OpenGL_IDirect3DDevice2 *odev;
146 const float id_mat[16] = {
153 *device = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(OpenGL_IDirect3DDevice2));
154 odev = (OpenGL_IDirect3DDevice2 *) (*device);
156 (*device)->lpvtbl = &OpenGL_vtable;
157 (*device)->d3d = d3d;
158 (*device)->surface = surface;
160 (*device)->viewport_list = NULL;
161 (*device)->current_viewport = NULL;
163 (*device)->set_context = set_context;
165 TRACE(ddraw, "OpenGL device created \n");
167 /* Create the OpenGL context */
168 odev->ctx = OSMesaCreateContext(OSMESA_RGBA, NULL);
169 odev->buffer = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
170 surface->s.surface_desc.dwWidth * surface->s.surface_desc.dwHeight * 4);
171 odev->rs.src = GL_ONE;
172 odev->rs.dst = GL_ZERO;
173 odev->rs.mag = GL_NEAREST;
174 odev->rs.min = GL_NEAREST;
177 memcpy(odev->world_mat, id_mat, 16 * sizeof(float));
178 memcpy(odev->view_mat , id_mat, 16 * sizeof(float));
179 memcpy(odev->proj_mat , id_mat, 16 * sizeof(float));
182 (*device)->set_context(*device);
183 glClearColor(0.0, 0.0, 0.0, 0.0);
184 glColor3f(1.0, 1.0, 1.0);
189 /* This is not the OpenGL UID */
193 /*******************************************************************************
194 * Common IDirect3DDevice2
197 static HRESULT WINAPI IDirect3DDevice2_QueryInterface(LPDIRECT3DDEVICE2 this,
203 WINE_StringFromCLSID((LPCLSID)riid,xrefiid);
204 FIXME(ddraw, "(%p)->(%s,%p): stub\n", this, xrefiid,ppvObj);
211 static ULONG WINAPI IDirect3DDevice2_AddRef(LPDIRECT3DDEVICE2 this)
213 TRACE(ddraw, "(%p)->()incrementing from %lu.\n", this, this->ref );
215 return ++(this->ref);
220 static ULONG WINAPI IDirect3DDevice2_Release(LPDIRECT3DDEVICE2 this)
222 FIXME( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
224 if (!--(this->ref)) {
225 HeapFree(GetProcessHeap(),0,this);
233 /*** IDirect3DDevice2 methods ***/
234 static HRESULT WINAPI IDirect3DDevice2_GetCaps(LPDIRECT3DDEVICE2 this,
235 LPD3DDEVICEDESC lpdescsoft,
236 LPD3DDEVICEDESC lpdeschard)
238 FIXME(ddraw, "(%p)->(%p,%p): stub\n", this, lpdescsoft, lpdeschard);
240 fill_opengl_caps(lpdescsoft, lpdeschard);
247 static HRESULT WINAPI IDirect3DDevice2_SwapTextureHandles(LPDIRECT3DDEVICE2 this,
248 LPDIRECT3DTEXTURE2 lptex1,
249 LPDIRECT3DTEXTURE2 lptex2)
251 FIXME(ddraw, "(%p)->(%p,%p): stub\n", this, lptex1, lptex2);
258 static HRESULT WINAPI IDirect3DDevice2_GetStats(LPDIRECT3DDEVICE2 this,
261 FIXME(ddraw, "(%p)->(%p): stub\n", this, lpstats);
268 static HRESULT WINAPI IDirect3DDevice2_AddViewport(LPDIRECT3DDEVICE2 this,
269 LPDIRECT3DVIEWPORT2 lpvp)
271 FIXME(ddraw, "(%p)->(%p): stub\n", this, lpvp);
273 /* Adds this viewport to the viewport list */
274 lpvp->next = this->viewport_list;
275 this->viewport_list = lpvp;
282 static HRESULT WINAPI IDirect3DDevice2_DeleteViewport(LPDIRECT3DDEVICE2 this,
283 LPDIRECT3DVIEWPORT2 lpvp)
285 LPDIRECT3DVIEWPORT2 cur, prev;
286 FIXME(ddraw, "(%p)->(%p): stub\n", this, lpvp);
288 /* Finds this viewport in the list */
290 cur = this->viewport_list;
291 while ((cur != NULL) && (cur != lpvp)) {
296 return DDERR_INVALIDOBJECT;
300 this->viewport_list = cur->next;
302 prev->next = cur->next;
309 static HRESULT WINAPI IDirect3DDevice2_NextViewport(LPDIRECT3DDEVICE2 this,
310 LPDIRECT3DVIEWPORT2 lpvp,
311 LPDIRECT3DVIEWPORT2* lplpvp,
314 FIXME(ddraw, "(%p)->(%p,%p,%08lx): stub\n", this, lpvp, lpvp, dwFlags);
318 *lplpvp = lpvp->next;
322 *lplpvp = this->viewport_list;
326 lpvp = this->viewport_list;
327 while (lpvp->next != NULL)
334 return DDERR_INVALIDPARAMS;
340 static HRESULT enum_texture_format_OpenGL(LPD3DENUMTEXTUREFORMATSCALLBACK cb,
343 LPDDPIXELFORMAT pformat;
345 /* Do the texture enumeration */
346 sdesc.dwSize = sizeof(DDSURFACEDESC);
347 sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
348 sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
349 pformat = &(sdesc.ddpfPixelFormat);
350 pformat->dwSize = sizeof(DDPIXELFORMAT);
351 pformat->dwFourCC = 0;
353 TRACE(ddraw, "Enumerating GL_RGBA unpacked (32)\n");
354 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
355 pformat->x.dwRGBBitCount = 32;
356 pformat->y.dwRBitMask = 0xFF000000;
357 pformat->z.dwGBitMask = 0x00FF0000;
358 pformat->xx.dwBBitMask = 0x0000FF00;
359 pformat->xy.dwRGBAlphaBitMask = 0x000000FF;
360 if (cb(&sdesc, context) == 0)
363 TRACE(ddraw, "Enumerating GL_RGB unpacked (24)\n");
364 pformat->dwFlags = DDPF_RGB;
365 pformat->x.dwRGBBitCount = 24;
366 pformat->y.dwRBitMask = 0x00FF0000;
367 pformat->z.dwGBitMask = 0x0000FF00;
368 pformat->xx.dwBBitMask = 0x000000FF;
369 pformat->xy.dwRGBAlphaBitMask = 0x00000000;
370 if (cb(&sdesc, context) == 0)
373 #ifndef HAVE_BUGGY_MESAGL
374 /* The packed texture format are buggy in Mesa. The bug was reported and corrected,
375 so that future version will work great. */
376 TRACE(ddraw, "Enumerating GL_RGB packed GL_UNSIGNED_SHORT_5_6_5 (16)\n");
377 pformat->dwFlags = DDPF_RGB;
378 pformat->x.dwRGBBitCount = 16;
379 pformat->y.dwRBitMask = 0x0000F800;
380 pformat->z.dwGBitMask = 0x000007E0;
381 pformat->xx.dwBBitMask = 0x0000001F;
382 pformat->xy.dwRGBAlphaBitMask = 0x00000000;
383 if (cb(&sdesc, context) == 0)
386 TRACE(ddraw, "Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_5_5_5_1 (16)\n");
387 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
388 pformat->x.dwRGBBitCount = 16;
389 pformat->y.dwRBitMask = 0x0000F800;
390 pformat->z.dwGBitMask = 0x000007C0;
391 pformat->xx.dwBBitMask = 0x0000003E;
392 pformat->xy.dwRGBAlphaBitMask = 0x00000001;
393 if (cb(&sdesc, context) == 0)
396 TRACE(ddraw, "Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_4_4_4_4 (16)\n");
397 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
398 pformat->x.dwRGBBitCount = 16;
399 pformat->y.dwRBitMask = 0x0000F000;
400 pformat->z.dwGBitMask = 0x00000F00;
401 pformat->xx.dwBBitMask = 0x000000F0;
402 pformat->xy.dwRGBAlphaBitMask = 0x0000000F;
403 if (cb(&sdesc, context) == 0)
406 TRACE(ddraw, "Enumerating GL_RGB packed GL_UNSIGNED_BYTE_3_3_2 (8)\n");
407 pformat->dwFlags = DDPF_RGB;
408 pformat->x.dwRGBBitCount = 8;
409 pformat->y.dwRBitMask = 0x0000F800;
410 pformat->z.dwGBitMask = 0x000007C0;
411 pformat->xx.dwBBitMask = 0x0000003E;
412 pformat->xy.dwRGBAlphaBitMask = 0x00000001;
413 if (cb(&sdesc, context) == 0)
417 TRACE(ddraw, "Enumerating Paletted (8)\n");
418 pformat->dwFlags = DDPF_PALETTEINDEXED8;
419 pformat->x.dwRGBBitCount = 8;
420 pformat->y.dwRBitMask = 0x00000000;
421 pformat->z.dwGBitMask = 0x00000000;
422 pformat->xx.dwBBitMask = 0x00000000;
423 pformat->xy.dwRGBAlphaBitMask = 0x00000000;
424 if (cb(&sdesc, context) == 0)
427 TRACE(ddraw, "End of enumeration\n");
432 static HRESULT WINAPI IDirect3DDevice2_EnumTextureFormats(LPDIRECT3DDEVICE2 this,
433 LPD3DENUMTEXTUREFORMATSCALLBACK cb,
436 FIXME(ddraw, "(%p)->(%p,%p): stub\n", this, cb, context);
438 return enum_texture_format_OpenGL(cb, context);
443 static HRESULT WINAPI IDirect3DDevice2_BeginScene(LPDIRECT3DDEVICE2 this)
445 /* OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) this; */
447 FIXME(ddraw, "(%p)->(): stub\n", this);
449 /* Here, we should get the DDraw surface and 'copy it' to the
450 OpenGL surface.... */
457 static HRESULT WINAPI IDirect3DDevice2_EndScene(LPDIRECT3DDEVICE2 this)
459 OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) this;
460 LPDIRECTDRAWSURFACE3 surf = (LPDIRECTDRAWSURFACE3) this->surface;
464 unsigned short *dest;
466 FIXME(ddraw, "(%p)->(): stub\n", this);
468 /* Here we copy back the OpenGL scene to the the DDraw surface */
469 /* First, lock the surface */
470 surf->lpvtbl->fnLock(surf,NULL,&sdesc,DDLOCK_WRITEONLY,0);
472 /* The copy the OpenGL buffer to this surface */
474 /* NOTE : this is only for debugging purpose. I KNOW it is really unoptimal.
475 I am currently working on a set of patches for Mesa to have OSMesa support
476 16 bpp surfaces => we will able to render directly onto the surface, no
477 need to do a bpp conversion */
478 dest = (unsigned short *) sdesc.y.lpSurface;
479 src = ((unsigned char *) odev->buffer) + 4 * (sdesc.dwWidth * (sdesc.dwHeight - 1));
480 for (y = 0; y < sdesc.dwHeight; y++) {
481 unsigned char *lsrc = src;
483 for (x = 0; x < sdesc.dwWidth ; x++) {
484 unsigned char r = *lsrc++;
485 unsigned char g = *lsrc++;
486 unsigned char b = *lsrc++;
488 *dest = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
493 src -= 4 * sdesc.dwWidth;
496 /* Unlock the surface */
497 surf->lpvtbl->fnUnlock(surf,sdesc.y.lpSurface);
504 static HRESULT WINAPI IDirect3DDevice2_GetDirect3D(LPDIRECT3DDEVICE2 this, LPDIRECT3D2 *lpd3d2)
506 TRACE(ddraw, "(%p)->(%p): stub\n", this, lpd3d2);
515 /*** DrawPrimitive API ***/
516 static HRESULT WINAPI IDirect3DDevice2_SetCurrentViewport(LPDIRECT3DDEVICE2 this,
517 LPDIRECT3DVIEWPORT2 lpvp)
519 FIXME(ddraw, "(%p)->(%p): stub\n", this, lpvp);
521 /* Should check if the viewport was added or not */
523 /* Set this viewport as the current viewport */
524 this->current_viewport = lpvp;
526 /* Activate this viewport */
527 lpvp->device.active_device2 = this;
528 lpvp->activate(lpvp);
535 static HRESULT WINAPI IDirect3DDevice2_GetCurrentViewport(LPDIRECT3DDEVICE2 this,
536 LPDIRECT3DVIEWPORT2 *lplpvp)
538 FIXME(ddraw, "(%p)->(%p): stub\n", this, lplpvp);
540 /* Returns the current viewport */
541 *lplpvp = this->current_viewport;
548 static HRESULT WINAPI IDirect3DDevice2_SetRenderTarget(LPDIRECT3DDEVICE2 this,
549 LPDIRECTDRAWSURFACE lpdds,
552 FIXME(ddraw, "(%p)->(%p,%08lx): stub\n", this, lpdds, dwFlags);
559 static HRESULT WINAPI IDirect3DDevice2_GetRenderTarget(LPDIRECT3DDEVICE2 this,
560 LPDIRECTDRAWSURFACE *lplpdds)
562 FIXME(ddraw, "(%p)->(%p): stub\n", this, lplpdds);
564 /* Returns the current rendering target (the surface on wich we render) */
565 *lplpdds = this->surface;
572 static HRESULT WINAPI IDirect3DDevice2_Begin(LPDIRECT3DDEVICE2 this,
573 D3DPRIMITIVETYPE d3dp,
577 FIXME(ddraw, "(%p)->(%d,%d,%08lx): stub\n", this, d3dp, d3dv, dwFlags);
584 static HRESULT WINAPI IDirect3DDevice2_BeginIndexed(LPDIRECT3DDEVICE2 this,
585 D3DPRIMITIVETYPE d3dp,
591 FIXME(ddraw, "(%p)->(%d,%d,%p,%ld,%08lx): stub\n", this, d3dp, d3dv, lpvert, numvert, dwFlags);
598 static HRESULT WINAPI IDirect3DDevice2_Vertex(LPDIRECT3DDEVICE2 this,
601 FIXME(ddraw, "(%p)->(%p): stub\n", this, lpvert);
608 static HRESULT WINAPI IDirect3DDevice2_Index(LPDIRECT3DDEVICE2 this,
611 FIXME(ddraw, "(%p)->(%d): stub\n", this, index);
618 static HRESULT WINAPI IDirect3DDevice2_End(LPDIRECT3DDEVICE2 this,
621 FIXME(ddraw, "(%p)->(%08lx): stub\n", this, dwFlags);
629 static HRESULT WINAPI IDirect3DDevice2_GetRenderState(LPDIRECT3DDEVICE2 this,
630 D3DRENDERSTATETYPE d3drs,
633 FIXME(ddraw, "(%p)->(%d,%p): stub\n", this, d3drs, lprstate);
640 static HRESULT WINAPI IDirect3DDevice2_SetRenderState(LPDIRECT3DDEVICE2 this,
641 D3DRENDERSTATETYPE dwRenderStateType,
644 OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) this;
646 TRACE(ddraw, "(%p)->(%d,%ld)\n", this, dwRenderStateType, dwRenderState);
648 /* Call the render state functions */
649 set_render_state(dwRenderStateType, dwRenderState, &(odev->rs));
656 static HRESULT WINAPI IDirect3DDevice2_GetLightState(LPDIRECT3DDEVICE2 this,
657 D3DLIGHTSTATETYPE d3dls,
660 FIXME(ddraw, "(%p)->(%d,%p): stub\n", this, d3dls, lplstate);
667 static HRESULT WINAPI IDirect3DDevice2_SetLightState(LPDIRECT3DDEVICE2 this,
668 D3DLIGHTSTATETYPE dwLightStateType,
671 FIXME(ddraw, "(%p)->(%d,%08lx): stub\n", this, dwLightStateType, dwLightState);
673 switch (dwLightStateType) {
674 case D3DLIGHTSTATE_MATERIAL: { /* 1 */
675 LPDIRECT3DMATERIAL2 mat = (LPDIRECT3DMATERIAL2) dwLightState;
680 TRACE(ddraw, "Zoups !!!\n");
684 case D3DLIGHTSTATE_AMBIENT: { /* 2 */
687 light[0] = ((dwLightState >> 16) & 0xFF) / 255.0;
688 light[1] = ((dwLightState >> 8) & 0xFF) / 255.0;
689 light[2] = ((dwLightState >> 0) & 0xFF) / 255.0;
691 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (float *) light);
694 case D3DLIGHTSTATE_COLORMODEL: /* 3 */
697 case D3DLIGHTSTATE_FOGMODE: /* 4 */
700 case D3DLIGHTSTATE_FOGSTART: /* 5 */
703 case D3DLIGHTSTATE_FOGEND: /* 6 */
706 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */
710 TRACE(ddraw, "Unexpected Light State Type\n");
711 return DDERR_INVALIDPARAMS;
719 static HRESULT WINAPI IDirect3DDevice2_SetTransform(LPDIRECT3DDEVICE2 this,
720 D3DTRANSFORMSTATETYPE d3dts,
721 LPD3DMATRIX lpmatrix)
723 OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) this;
725 FIXME(ddraw, "(%p)->(%d,%p): stub\n", this, d3dts, lpmatrix);
727 /* Using a trial and failure approach, I found that the order of
728 Direct3D transformations that works best is :
730 ScreenCoord = ProjectionMat * ViewMat * WorldMat * ObjectCoord
732 As OpenGL uses only two matrices, I combined PROJECTION and VIEW into
733 OpenGL's GL_PROJECTION matrix and the WORLD into GL_MODELVIEW.
735 If anyone has a good explanation of the three different matrices in
736 the SDK online documentation, feel free to point it to me. For example,
737 which matrices transform lights ? In OpenGL only the PROJECTION matrix
738 transform the lights, not the MODELVIEW. Using the matrix names, I
739 supposed that PROJECTION and VIEW (all 'camera' related names) do
740 transform lights, but WORLD do not. It may be wrong though... */
742 /* After reading through both OpenGL and Direct3D documentations, I
743 thought that D3D matrices were written in 'line major mode' transposed
744 from OpenGL's 'column major mode'. But I found out that a simple memcpy
745 works fine to transfer one matrix format to the other (it did not work
746 when transposing)....
749 1) are the documentations wrong
750 2) does the matrix work even if they are not read correctly
751 3) is Mesa's implementation of OpenGL not compliant regarding Matrix
752 loading using glLoadMatrix ?
754 Anyway, I always use 'conv_mat' to transfer the matrices from one format
755 to the other so that if I ever find out that I need to transpose them, I
756 will able to do it quickly, only by changing the macro conv_mat. */
759 case D3DTRANSFORMSTATE_WORLD: {
760 conv_mat(lpmatrix, odev->world_mat);
761 glMatrixMode(GL_MODELVIEW);
762 glLoadMatrixf((float *) &(odev->world_mat));
765 case D3DTRANSFORMSTATE_VIEW: {
766 conv_mat(lpmatrix, odev->view_mat);
767 glMatrixMode(GL_PROJECTION);
768 glLoadMatrixf((float *) &(odev->proj_mat));
769 glMultMatrixf((float *) &(odev->view_mat));
772 case D3DTRANSFORMSTATE_PROJECTION: {
773 conv_mat(lpmatrix, odev->proj_mat);
774 glMatrixMode(GL_PROJECTION);
775 glLoadMatrixf((float *) &(odev->proj_mat));
776 glMultMatrixf((float *) &(odev->view_mat));
788 static HRESULT WINAPI IDirect3DDevice2_GetTransform(LPDIRECT3DDEVICE2 this,
789 D3DTRANSFORMSTATETYPE d3dts,
790 LPD3DMATRIX lpmatrix)
792 FIXME(ddraw, "(%p)->(%d,%p): stub\n", this, d3dts, lpmatrix);
799 static HRESULT WINAPI IDirect3DDevice2_MultiplyTransform(LPDIRECT3DDEVICE2 this,
800 D3DTRANSFORMSTATETYPE d3dts,
801 LPD3DMATRIX lpmatrix)
803 FIXME(ddraw, "(%p)->(%d,%p): stub\n", this, d3dts, lpmatrix);
808 #define DRAW_PRIMITIVE(MAXVERT,INDEX) \
809 /* Puts GL in the correct lighting mode */ \
810 if (odev->vt != d3dv) { \
811 if (odev->vt == D3DVT_TLVERTEX) { \
812 /* Need to put the correct transformation again */ \
813 glMatrixMode(GL_MODELVIEW); \
814 glLoadMatrixf((float *) &(odev->world_mat)); \
815 glMatrixMode(GL_PROJECTION); \
816 glLoadMatrixf((float *) &(odev->proj_mat)); \
817 glMultMatrixf((float *) &(odev->view_mat)); \
822 TRACE(ddraw, "Standard Vertex\n"); \
823 glEnable(GL_LIGHTING); \
826 case D3DVT_LVERTEX: \
827 TRACE(ddraw, "Lighted Vertex\n"); \
828 glDisable(GL_LIGHTING); \
831 case D3DVT_TLVERTEX: { \
832 GLdouble height, width, minZ, maxZ; \
834 TRACE(ddraw, "Transformed - Lighted Vertex\n"); \
835 /* First, disable lighting */ \
836 glDisable(GL_LIGHTING); \
838 /* Then do not put any transformation matrixes */ \
839 glMatrixMode(GL_MODELVIEW); \
841 glMatrixMode(GL_PROJECTION); \
844 if (this->current_viewport == NULL) { \
845 ERR(ddraw, "No current viewport !\n"); \
846 /* Using standard values */ \
852 if (this->current_viewport->use_vp2) { \
853 height = (GLdouble) this->current_viewport->viewport.vp2.dwHeight; \
854 width = (GLdouble) this->current_viewport->viewport.vp2.dwWidth; \
855 minZ = (GLdouble) this->current_viewport->viewport.vp2.dvMinZ; \
856 maxZ = (GLdouble) this->current_viewport->viewport.vp2.dvMaxZ; \
858 height = (GLdouble) this->current_viewport->viewport.vp1.dwHeight; \
859 width = (GLdouble) this->current_viewport->viewport.vp1.dwWidth; \
860 minZ = (GLdouble) this->current_viewport->viewport.vp1.dvMinZ; \
861 maxZ = (GLdouble) this->current_viewport->viewport.vp1.dvMaxZ; \
865 glOrtho(0.0, width, height, 0.0, -minZ, -maxZ); \
869 ERR(ddraw, "Unhandled vertex type\n"); \
877 case D3DPT_POINTLIST: \
878 TRACE(ddraw, "Start POINTS\n"); \
879 glBegin(GL_POINTS); \
882 case D3DPT_LINELIST: \
883 TRACE(ddraw, "Start LINES\n"); \
887 case D3DPT_LINESTRIP: \
888 TRACE(ddraw, "Start LINE_STRIP\n"); \
889 glBegin(GL_LINE_STRIP); \
892 case D3DPT_TRIANGLELIST: \
893 TRACE(ddraw, "Start TRIANGLES\n"); \
894 glBegin(GL_TRIANGLES); \
897 case D3DPT_TRIANGLESTRIP: \
898 TRACE(ddraw, "Start TRIANGLE_STRIP\n"); \
899 glBegin(GL_TRIANGLE_STRIP); \
902 case D3DPT_TRIANGLEFAN: \
903 TRACE(ddraw, "Start TRIANGLE_FAN\n"); \
904 glBegin(GL_TRIANGLE_FAN); \
908 TRACE(ddraw, "Unhandled primitive\n"); \
912 /* Draw the primitives */ \
913 for (vx_index = 0; vx_index < MAXVERT; vx_index++) { \
915 case D3DVT_VERTEX: { \
916 D3DVERTEX *vx = ((D3DVERTEX *) lpvertex) + INDEX; \
918 glNormal3f(vx->nx.nx, vx->ny.ny, vx->nz.nz); \
919 glVertex3f(vx->x.x, vx->y.y, vx->z.z); \
920 TRACE(ddraw, " V: %f %f %f\n", vx->x.x, vx->y.y, vx->z.z); \
923 case D3DVT_LVERTEX: { \
924 D3DLVERTEX *vx = ((D3DLVERTEX *) lpvertex) + INDEX; \
925 DWORD col = vx->c.color; \
927 glColor3f(((col >> 16) & 0xFF) / 255.0, \
928 ((col >> 8) & 0xFF) / 255.0, \
929 ((col >> 0) & 0xFF) / 255.0); \
930 glVertex3f(vx->x.x, vx->y.y, vx->z.z); \
931 TRACE(ddraw, " LV: %f %f %f (%02lx %02lx %02lx)\n", \
932 vx->x.x, vx->y.y, vx->z.z, \
933 ((col >> 16) & 0xFF), ((col >> 8) & 0xFF), ((col >> 0) & 0xFF)); \
936 case D3DVT_TLVERTEX: { \
937 D3DTLVERTEX *vx = ((D3DTLVERTEX *) lpvertex) + INDEX; \
938 DWORD col = vx->c.color; \
940 glColor3f(((col >> 16) & 0xFF) / 255.0, \
941 ((col >> 8) & 0xFF) / 255.0, \
942 ((col >> 0) & 0xFF) / 255.0); \
943 glTexCoord2f(vx->u.tu, vx->v.tv); \
944 if (vx->r.rhw < 0.01) \
945 glVertex3f(vx->x.sx, \
949 glVertex4f(vx->x.sx / vx->r.rhw, \
950 vx->y.sy / vx->r.rhw, \
951 vx->z.sz / vx->r.rhw, \
953 TRACE(ddraw, " TLV: %f %f %f (%02lx %02lx %02lx) (%f %f) (%f)\n", \
954 vx->x.sx, vx->y.sy, vx->z.sz, \
955 ((col >> 16) & 0xFF), ((col >> 8) & 0xFF), ((col >> 0) & 0xFF), \
956 vx->u.tu, vx->v.tv, vx->r.rhw); \
960 TRACE(ddraw, "Unhandled vertex type\n"); \
966 TRACE(ddraw, "End\n");
969 static HRESULT WINAPI IDirect3DDevice2_DrawPrimitive(LPDIRECT3DDEVICE2 this,
970 D3DPRIMITIVETYPE d3dp,
976 OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) this;
979 TRACE(ddraw, "(%p)->(%d,%d,%p,%ld,%08lx): stub\n", this, d3dp, d3dv, lpvertex, vertcount, dwFlags);
981 DRAW_PRIMITIVE(vertcount, vx_index);
988 static HRESULT WINAPI IDirect3DDevice2_DrawIndexedPrimitive(LPDIRECT3DDEVICE2 this,
989 D3DPRIMITIVETYPE d3dp,
997 OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) this;
1000 TRACE(ddraw, "(%p)->(%d,%d,%p,%ld,%p,%ld,%08lx): stub\n", this, d3dp, d3dv, lpvertex, vertcount, lpindexes, indexcount, dwFlags);
1002 DRAW_PRIMITIVE(indexcount, lpindexes[vx_index]);
1009 static HRESULT WINAPI IDirect3DDevice2_SetClipStatus(LPDIRECT3DDEVICE2 this,
1010 LPD3DCLIPSTATUS lpcs)
1012 FIXME(ddraw, "(%p)->(%p): stub\n", this, lpcs);
1019 static HRESULT WINAPI IDirect3DDevice2_GetClipStatus(LPDIRECT3DDEVICE2 this,
1020 LPD3DCLIPSTATUS lpcs)
1022 FIXME(ddraw, "(%p)->(%p): stub\n", this, lpcs);
1029 /*******************************************************************************
1030 * OpenGL-specific IDirect3DDevice2
1033 /*******************************************************************************
1034 * OpenGL-specific VTable
1037 static IDirect3DDevice2_VTable OpenGL_vtable = {
1038 IDirect3DDevice2_QueryInterface,
1039 IDirect3DDevice2_AddRef,
1040 IDirect3DDevice2_Release,
1041 /*** IDirect3DDevice2 methods ***/
1042 IDirect3DDevice2_GetCaps,
1043 IDirect3DDevice2_SwapTextureHandles,
1044 IDirect3DDevice2_GetStats,
1045 IDirect3DDevice2_AddViewport,
1046 IDirect3DDevice2_DeleteViewport,
1047 IDirect3DDevice2_NextViewport,
1048 IDirect3DDevice2_EnumTextureFormats,
1049 IDirect3DDevice2_BeginScene,
1050 IDirect3DDevice2_EndScene,
1051 IDirect3DDevice2_GetDirect3D,
1053 /*** DrawPrimitive API ***/
1054 IDirect3DDevice2_SetCurrentViewport,
1055 IDirect3DDevice2_GetCurrentViewport,
1057 IDirect3DDevice2_SetRenderTarget,
1058 IDirect3DDevice2_GetRenderTarget,
1060 IDirect3DDevice2_Begin,
1061 IDirect3DDevice2_BeginIndexed,
1062 IDirect3DDevice2_Vertex,
1063 IDirect3DDevice2_Index,
1064 IDirect3DDevice2_End,
1066 IDirect3DDevice2_GetRenderState,
1067 IDirect3DDevice2_SetRenderState,
1068 IDirect3DDevice2_GetLightState,
1069 IDirect3DDevice2_SetLightState,
1070 IDirect3DDevice2_SetTransform,
1071 IDirect3DDevice2_GetTransform,
1072 IDirect3DDevice2_MultiplyTransform,
1074 IDirect3DDevice2_DrawPrimitive,
1075 IDirect3DDevice2_DrawIndexedPrimitive,
1077 IDirect3DDevice2_SetClipStatus,
1078 IDirect3DDevice2_GetClipStatus,
1081 /*******************************************************************************
1084 int d3d_OpenGL_dx3(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) {
1085 D3DDEVICEDESC d1,d2;
1087 TRACE(ddraw," Enumerating OpenGL D3D device.\n");
1089 fill_opengl_caps(&d1, &d2);
1091 return cb((void*)&IID_D3DDEVICE_OpenGL,"WINE Direct3D using OpenGL","direct3d",&d1,&d2,context);
1094 float id_mat[16] = {
1101 int is_OpenGL_dx3(REFCLSID rguid, LPDIRECTDRAWSURFACE surface, LPDIRECT3DDEVICE *device)
1103 if (!memcmp(&IID_D3DDEVICE_OpenGL,rguid,sizeof(IID_D3DDEVICE_OpenGL))) {
1104 OpenGL_IDirect3DDevice *odev;
1106 *device = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(OpenGL_IDirect3DDevice));
1107 odev = (OpenGL_IDirect3DDevice *) (*device);
1109 (*device)->lpvtbl = &OpenGL_vtable_dx3;
1110 (*device)->d3d = NULL;
1111 (*device)->surface = surface;
1113 (*device)->viewport_list = NULL;
1114 (*device)->current_viewport = NULL;
1116 (*device)->set_context = set_context_dx3;
1118 TRACE(ddraw, "OpenGL device created \n");
1120 /* Create the OpenGL context */
1121 odev->ctx = OSMesaCreateContext(OSMESA_RGBA, NULL);
1122 odev->buffer = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
1123 surface->s.surface_desc.dwWidth * surface->s.surface_desc.dwHeight * 4);
1124 odev->rs.src = GL_ONE;
1125 odev->rs.dst = GL_ZERO;
1126 odev->rs.mag = GL_NEAREST;
1127 odev->rs.min = GL_NEAREST;
1129 odev->world_mat = (LPD3DMATRIX) &id_mat;
1130 odev->view_mat = (LPD3DMATRIX) &id_mat;
1131 odev->proj_mat = (LPD3DMATRIX) &id_mat;
1133 /* Initialisation */
1134 (*device)->set_context(*device);
1135 glClearColor(0.0, 0.0, 0.0, 0.0);
1136 glColor3f(1.0, 1.0, 1.0);
1141 /* This is not the OpenGL UID */
1146 /*******************************************************************************
1149 static HRESULT WINAPI IDirect3DDevice_QueryInterface(LPDIRECT3DDEVICE this,
1155 WINE_StringFromCLSID((LPCLSID)riid,xrefiid);
1156 FIXME(ddraw, "(%p)->(%s,%p): stub\n", this, xrefiid,ppvObj);
1163 static ULONG WINAPI IDirect3DDevice_AddRef(LPDIRECT3DDEVICE this)
1165 TRACE(ddraw, "(%p)->()incrementing from %lu.\n", this, this->ref );
1167 return ++(this->ref);
1172 static ULONG WINAPI IDirect3DDevice_Release(LPDIRECT3DDEVICE this)
1174 FIXME( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1176 if (!--(this->ref)) {
1177 HeapFree(GetProcessHeap(),0,this);
1184 static HRESULT WINAPI IDirect3DDevice_Initialize(LPDIRECT3DDEVICE this,
1187 LPD3DDEVICEDESC lpd3ddvdesc)
1189 TRACE(ddraw, "(%p)->(%p,%p,%p): stub\n", this, lpd3d,lpGUID, lpd3ddvdesc);
1191 return DDERR_ALREADYINITIALIZED;
1195 static HRESULT WINAPI IDirect3DDevice_GetCaps(LPDIRECT3DDEVICE this,
1196 LPD3DDEVICEDESC lpD3DHWDevDesc,
1197 LPD3DDEVICEDESC lpD3DSWDevDesc)
1199 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpD3DHWDevDesc, lpD3DSWDevDesc);
1201 fill_opengl_caps(lpD3DHWDevDesc, lpD3DSWDevDesc);
1207 static HRESULT WINAPI IDirect3DDevice_SwapTextureHandles(LPDIRECT3DDEVICE this,
1208 LPDIRECT3DTEXTURE lpD3DTex1,
1209 LPDIRECT3DTEXTURE lpD3DTex2)
1211 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpD3DTex1, lpD3DTex2);
1216 static HRESULT WINAPI IDirect3DDevice_CreateExecuteBuffer(LPDIRECT3DDEVICE this,
1217 LPD3DEXECUTEBUFFERDESC lpDesc,
1218 LPDIRECT3DEXECUTEBUFFER *lplpDirect3DExecuteBuffer,
1219 IUnknown *pUnkOuter)
1221 TRACE(ddraw, "(%p)->(%p,%p,%p)\n", this, lpDesc, lplpDirect3DExecuteBuffer, pUnkOuter);
1223 *lplpDirect3DExecuteBuffer = d3dexecutebuffer_create(this, lpDesc);
1229 static HRESULT WINAPI IDirect3DDevice_GetStats(LPDIRECT3DDEVICE this,
1230 LPD3DSTATS lpD3DStats)
1232 TRACE(ddraw, "(%p)->(%p): stub\n", this, lpD3DStats);
1238 static HRESULT WINAPI IDirect3DDevice_Execute(LPDIRECT3DDEVICE this,
1239 LPDIRECT3DEXECUTEBUFFER lpDirect3DExecuteBuffer,
1240 LPDIRECT3DVIEWPORT lpDirect3DViewport,
1243 TRACE(ddraw, "(%p)->(%p,%p,%08ld): stub\n", this, lpDirect3DExecuteBuffer, lpDirect3DViewport, dwFlags);
1245 /* Put this as the default context */
1248 lpDirect3DExecuteBuffer->execute(lpDirect3DExecuteBuffer, this, lpDirect3DViewport);
1253 static HRESULT WINAPI IDirect3DDevice_AddViewport(LPDIRECT3DDEVICE this,
1254 LPDIRECT3DVIEWPORT lpvp)
1256 FIXME(ddraw, "(%p)->(%p): stub\n", this, lpvp);
1258 /* Adds this viewport to the viewport list */
1259 lpvp->next = this->viewport_list;
1260 this->viewport_list = lpvp;
1267 static HRESULT WINAPI IDirect3DDevice_DeleteViewport(LPDIRECT3DDEVICE this,
1268 LPDIRECT3DVIEWPORT lpvp)
1270 LPDIRECT3DVIEWPORT cur, prev;
1271 FIXME(ddraw, "(%p)->(%p): stub\n", this, lpvp);
1273 /* Finds this viewport in the list */
1275 cur = this->viewport_list;
1276 while ((cur != NULL) && (cur != lpvp)) {
1281 return DDERR_INVALIDOBJECT;
1285 this->viewport_list = cur->next;
1287 prev->next = cur->next;
1294 static HRESULT WINAPI IDirect3DDevice_NextViewport(LPDIRECT3DDEVICE this,
1295 LPDIRECT3DVIEWPORT lpvp,
1296 LPDIRECT3DVIEWPORT* lplpvp,
1299 FIXME(ddraw, "(%p)->(%p,%p,%08lx): stub\n", this, lpvp, lpvp, dwFlags);
1303 *lplpvp = lpvp->next;
1307 *lplpvp = this->viewport_list;
1311 lpvp = this->viewport_list;
1312 while (lpvp->next != NULL)
1319 return DDERR_INVALIDPARAMS;
1325 static HRESULT WINAPI IDirect3DDevice_Pick(LPDIRECT3DDEVICE this,
1326 LPDIRECT3DEXECUTEBUFFER lpDirect3DExecuteBuffer,
1327 LPDIRECT3DVIEWPORT lpDirect3DViewport,
1331 TRACE(ddraw, "(%p)->(%p,%p,%08lx,%p): stub\n", this, lpDirect3DExecuteBuffer, lpDirect3DViewport,
1338 static HRESULT WINAPI IDirect3DDevice_GetPickRecords(LPDIRECT3DDEVICE this,
1340 LPD3DPICKRECORD lpD3DPickRec)
1342 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpCount, lpD3DPickRec);
1348 static HRESULT WINAPI IDirect3DDevice_EnumTextureFormats(LPDIRECT3DDEVICE this,
1349 LPD3DENUMTEXTUREFORMATSCALLBACK lpd3dEnumTextureProc,
1352 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpd3dEnumTextureProc, lpArg);
1354 return enum_texture_format_OpenGL(lpd3dEnumTextureProc, lpArg);
1358 static HRESULT WINAPI IDirect3DDevice_CreateMatrix(LPDIRECT3DDEVICE this,
1359 LPD3DMATRIXHANDLE lpD3DMatHandle)
1361 TRACE(ddraw, "(%p)->(%p)\n", this, lpD3DMatHandle);
1363 *lpD3DMatHandle = (D3DMATRIXHANDLE) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(D3DMATRIX));
1369 static HRESULT WINAPI IDirect3DDevice_SetMatrix(LPDIRECT3DDEVICE this,
1370 D3DMATRIXHANDLE d3dMatHandle,
1371 const LPD3DMATRIX lpD3DMatrix)
1373 TRACE(ddraw, "(%p)->(%08lx,%p)\n", this, d3dMatHandle, lpD3DMatrix);
1375 dump_mat(lpD3DMatrix);
1377 *((D3DMATRIX *) d3dMatHandle) = *lpD3DMatrix;
1383 static HRESULT WINAPI IDirect3DDevice_GetMatrix(LPDIRECT3DDEVICE this,
1384 D3DMATRIXHANDLE D3DMatHandle,
1385 LPD3DMATRIX lpD3DMatrix)
1387 TRACE(ddraw, "(%p)->(%08lx,%p)\n", this, D3DMatHandle, lpD3DMatrix);
1389 *lpD3DMatrix = *((D3DMATRIX *) D3DMatHandle);
1395 static HRESULT WINAPI IDirect3DDevice_DeleteMatrix(LPDIRECT3DDEVICE this,
1396 D3DMATRIXHANDLE d3dMatHandle)
1398 TRACE(ddraw, "(%p)->(%08lx)\n", this, d3dMatHandle);
1400 HeapFree(GetProcessHeap(),0, (void *) d3dMatHandle);
1406 static HRESULT WINAPI IDirect3DDevice_BeginScene(LPDIRECT3DDEVICE this)
1408 /* OpenGL_IDirect3DDevice *odev = (OpenGL_IDirect3DDevice *) this; */
1410 FIXME(ddraw, "(%p)->(): stub\n", this);
1412 /* We get the pointer to the surface (should be done on flip) */
1413 /* odev->zb->pbuf = this->surface->s.surface_desc.y.lpSurface; */
1419 /* This is for the moment copy-pasted from IDirect3DDevice2...
1420 Will make a common function ... */
1421 static HRESULT WINAPI IDirect3DDevice_EndScene(LPDIRECT3DDEVICE this)
1423 OpenGL_IDirect3DDevice *odev = (OpenGL_IDirect3DDevice *) this;
1424 LPDIRECTDRAWSURFACE3 surf = (LPDIRECTDRAWSURFACE3) this->surface;
1425 DDSURFACEDESC sdesc;
1428 unsigned short *dest;
1430 FIXME(ddraw, "(%p)->(): stub\n", this);
1432 /* Here we copy back the OpenGL scene to the the DDraw surface */
1433 /* First, lock the surface */
1434 surf->lpvtbl->fnLock(surf,NULL,&sdesc,DDLOCK_WRITEONLY,0);
1436 /* The copy the OpenGL buffer to this surface */
1438 /* NOTE : this is only for debugging purpose. I KNOW it is really unoptimal.
1439 I am currently working on a set of patches for Mesa to have OSMesa support
1440 16 bpp surfaces => we will able to render directly onto the surface, no
1441 need to do a bpp conversion */
1442 dest = (unsigned short *) sdesc.y.lpSurface;
1443 src = ((unsigned char *) odev->buffer) + 4 * (sdesc.dwWidth * (sdesc.dwHeight - 1));
1444 for (y = 0; y < sdesc.dwHeight; y++) {
1445 unsigned char *lsrc = src;
1447 for (x = 0; x < sdesc.dwWidth ; x++) {
1448 unsigned char r = *lsrc++;
1449 unsigned char g = *lsrc++;
1450 unsigned char b = *lsrc++;
1453 *dest = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
1458 src -= 4 * sdesc.dwWidth;
1461 /* Unlock the surface */
1462 surf->lpvtbl->fnUnlock(surf,sdesc.y.lpSurface);
1468 static HRESULT WINAPI IDirect3DDevice_GetDirect3D(LPDIRECT3DDEVICE this,
1469 LPDIRECT3D *lpDirect3D)
1471 TRACE(ddraw, "(%p)->(%p): stub\n", this, lpDirect3D);
1478 /*******************************************************************************
1479 * Direct3DDevice VTable
1481 static IDirect3DDevice_VTable OpenGL_vtable_dx3 = {
1482 IDirect3DDevice_QueryInterface,
1483 IDirect3DDevice_AddRef,
1484 IDirect3DDevice_Release,
1485 IDirect3DDevice_Initialize,
1486 IDirect3DDevice_GetCaps,
1487 IDirect3DDevice_SwapTextureHandles,
1488 IDirect3DDevice_CreateExecuteBuffer,
1489 IDirect3DDevice_GetStats,
1490 IDirect3DDevice_Execute,
1491 IDirect3DDevice_AddViewport,
1492 IDirect3DDevice_DeleteViewport,
1493 IDirect3DDevice_NextViewport,
1494 IDirect3DDevice_Pick,
1495 IDirect3DDevice_GetPickRecords,
1496 IDirect3DDevice_EnumTextureFormats,
1497 IDirect3DDevice_CreateMatrix,
1498 IDirect3DDevice_SetMatrix,
1499 IDirect3DDevice_GetMatrix,
1500 IDirect3DDevice_DeleteMatrix,
1501 IDirect3DDevice_BeginScene,
1502 IDirect3DDevice_EndScene,
1503 IDirect3DDevice_GetDirect3D,
1506 #else /* HAVE_MESAGL */
1508 int d3d_OpenGL(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) {
1512 int is_OpenGL(REFCLSID rguid, LPDIRECTDRAWSURFACE surface, LPDIRECT3DDEVICE2 *device, LPDIRECT3D2 d3d)
1517 int d3d_OpenGL_dx3(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) {
1521 int is_OpenGL_dx3(REFCLSID rguid, LPDIRECTDRAWSURFACE surface, LPDIRECT3DDEVICE *device)
1526 #endif /* HAVE_MESAGL */