4 This files contains all the D3D devices that Wine supports. For the moment
5 only the 'OpenGL' target is supported. */
10 #include "wine/obj_base.h"
16 #include "d3d_private.h"
18 /* Define this variable if you have an unpatched Mesa 3.0 (patches are available
19 on Mesa's home page) or version 3.1b.
21 Version 3.2b should correct this bug */
22 #undef HAVE_BUGGY_MESAGL
26 static GUID IID_D3DDEVICE2_OpenGL = {
30 { 0x8b,0x7c,0x0e,0x4e,0xd8,0x3c,0x2b,0x3c }
33 static GUID IID_D3DDEVICE_OpenGL = {
37 { 0x82,0x2d,0xa8,0xd5,0x31,0x87,0xca,0xfa }
41 static IDirect3DDevice2_VTable OpenGL_vtable;
42 static IDirect3DDevice_VTable OpenGL_vtable_dx3;
44 /*******************************************************************************
45 * OpenGL static functions
47 static void set_context(LPDIRECT3DDEVICE2 this) {
48 OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) this;
50 OSMesaMakeCurrent(odev->ctx, odev->buffer,
52 this->surface->s.surface_desc.dwWidth,
53 this->surface->s.surface_desc.dwHeight);
56 static void set_context_dx3(LPDIRECT3DDEVICE this) {
57 OpenGL_IDirect3DDevice *odev = (OpenGL_IDirect3DDevice *) this;
59 OSMesaMakeCurrent(odev->ctx, odev->buffer,
61 this->surface->s.surface_desc.dwWidth,
62 this->surface->s.surface_desc.dwHeight);
65 static void fill_opengl_primcaps(D3DPRIMCAPS *pc)
67 pc->dwSize = sizeof(*pc);
68 pc->dwMiscCaps = D3DPMISCCAPS_CONFORMANT | D3DPMISCCAPS_CULLCCW | D3DPMISCCAPS_CULLCW |
69 D3DPMISCCAPS_LINEPATTERNREP | D3DPMISCCAPS_MASKZ;
70 pc->dwRasterCaps = D3DPRASTERCAPS_DITHER | D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_FOGTABLE |
71 D3DPRASTERCAPS_FOGVERTEX | D3DPRASTERCAPS_STIPPLE | D3DPRASTERCAPS_ZBIAS | D3DPRASTERCAPS_ZTEST;
72 pc->dwZCmpCaps = 0xFFFFFFFF; /* All Z test can be done */
73 pc->dwSrcBlendCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
74 pc->dwDestBlendCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
75 pc->dwAlphaCmpCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
76 pc->dwShadeCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
77 pc->dwTextureCaps = D3DPTEXTURECAPS_ALPHA | D3DPTEXTURECAPS_BORDER | D3DPTEXTURECAPS_PERSPECTIVE |
78 D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_TRANSPARENCY;
79 pc->dwTextureFilterCaps = D3DPTFILTERCAPS_LINEAR | D3DPTFILTERCAPS_LINEARMIPLINEAR | D3DPTFILTERCAPS_LINEARMIPNEAREST |
80 D3DPTFILTERCAPS_MIPLINEAR | D3DPTFILTERCAPS_MIPNEAREST | D3DPTFILTERCAPS_NEAREST;
81 pc->dwTextureBlendCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
82 pc->dwTextureAddressCaps = D3DPTADDRESSCAPS_BORDER | D3DPTADDRESSCAPS_CLAMP | D3DPTADDRESSCAPS_WRAP;
83 pc->dwStippleWidth = 32;
84 pc->dwStippleHeight = 32;
87 static void fill_opengl_caps(D3DDEVICEDESC *d1, D3DDEVICEDESC *d2)
91 d1->dwSize = sizeof(*d1);
92 d1->dwFlags = D3DDD_DEVCAPS | D3DDD_BCLIPPING | D3DDD_COLORMODEL | D3DDD_DEVICERENDERBITDEPTH | D3DDD_DEVICEZBUFFERBITDEPTH
93 | D3DDD_LIGHTINGCAPS | D3DDD_LINECAPS | D3DDD_MAXBUFFERSIZE | D3DDD_MAXVERTEXCOUNT | D3DDD_TRANSFORMCAPS | D3DDD_TRICAPS;
94 d1->dcmColorModel = D3DCOLOR_RGB;
95 d1->dwDevCaps = D3DDEVCAPS_CANRENDERAFTERFLIP | D3DDEVCAPS_DRAWPRIMTLVERTEX | D3DDEVCAPS_EXECUTESYSTEMMEMORY |
96 D3DDEVCAPS_EXECUTEVIDEOMEMORY | D3DDEVCAPS_FLOATTLVERTEX | D3DDEVCAPS_TEXTURENONLOCALVIDMEM | D3DDEVCAPS_TEXTURESYSTEMMEMORY |
97 D3DDEVCAPS_TEXTUREVIDEOMEMORY | D3DDEVCAPS_TLVERTEXSYSTEMMEMORY | D3DDEVCAPS_TLVERTEXVIDEOMEMORY;
98 d1->dtcTransformCaps.dwSize = sizeof(D3DTRANSFORMCAPS);
99 d1->dtcTransformCaps.dwCaps = D3DTRANSFORMCAPS_CLIP;
100 d1->bClipping = TRUE;
101 d1->dlcLightingCaps.dwSize = sizeof(D3DLIGHTINGCAPS);
102 d1->dlcLightingCaps.dwCaps = D3DLIGHTCAPS_DIRECTIONAL | D3DLIGHTCAPS_PARALLELPOINT | D3DLIGHTCAPS_POINT | D3DLIGHTCAPS_SPOT;
103 d1->dlcLightingCaps.dwLightingModel = D3DLIGHTINGMODEL_RGB;
104 d1->dlcLightingCaps.dwNumLights = 16; /* glGetIntegerv(GL_MAX_LIGHTS, &maxlight); d1->dlcLightingCaps.dwNumLights = maxlight; */
105 fill_opengl_primcaps(&(d1->dpcLineCaps));
106 fill_opengl_primcaps(&(d1->dpcTriCaps));
107 d1->dwDeviceRenderBitDepth = DDBD_16;
108 d1->dwDeviceZBufferBitDepth = DDBD_16;
109 d1->dwMaxBufferSize = 0;
110 d1->dwMaxVertexCount = 65536;
111 d1->dwMinTextureWidth = 1;
112 d1->dwMinTextureHeight = 1;
113 d1->dwMaxTextureWidth = 256; /* This is for Mesa on top of Glide (in the future :-) ) */
114 d1->dwMaxTextureHeight = 256; /* This is for Mesa on top of Glide (in the future :-) ) */
115 d1->dwMinStippleWidth = 1;
116 d1->dwMinStippleHeight = 1;
117 d1->dwMaxStippleWidth = 32;
118 d1->dwMaxStippleHeight = 32;
120 d2->dwSize = sizeof(*d2);
124 int d3d_OpenGL(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) {
127 TRACE(ddraw," Enumerating OpenGL D3D device.\n");
129 fill_opengl_caps(&d1, &d2);
131 return cb((void*)&IID_D3DDEVICE2_OpenGL,"WINE Direct3D using OpenGL","direct3d",&d1,&d2,context);
134 int is_OpenGL(REFCLSID rguid, LPDIRECTDRAWSURFACE surface, LPDIRECT3DDEVICE2 *device, LPDIRECT3D2 d3d)
136 if (/* Default device */
139 (!memcmp(&IID_IDirect3DHALDevice,rguid,sizeof(IID_IDirect3DHALDevice))) ||
141 (!memcmp(&IID_D3DDEVICE2_OpenGL,rguid,sizeof(IID_D3DDEVICE2_OpenGL)))) {
142 OpenGL_IDirect3DDevice2 *odev;
144 const float id_mat[16] = {
151 *device = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(OpenGL_IDirect3DDevice2));
152 odev = (OpenGL_IDirect3DDevice2 *) (*device);
154 (*device)->lpvtbl = &OpenGL_vtable;
155 (*device)->d3d = d3d;
156 (*device)->surface = surface;
158 (*device)->viewport_list = NULL;
159 (*device)->current_viewport = NULL;
161 (*device)->set_context = set_context;
163 TRACE(ddraw, "OpenGL device created \n");
165 /* Create the OpenGL context */
166 odev->ctx = OSMesaCreateContext(OSMESA_RGBA, NULL);
167 odev->buffer = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
168 surface->s.surface_desc.dwWidth * surface->s.surface_desc.dwHeight * 4);
169 odev->rs.src = GL_ONE;
170 odev->rs.dst = GL_ZERO;
171 odev->rs.mag = GL_NEAREST;
172 odev->rs.min = GL_NEAREST;
175 memcpy(odev->world_mat, id_mat, 16 * sizeof(float));
176 memcpy(odev->view_mat , id_mat, 16 * sizeof(float));
177 memcpy(odev->proj_mat , id_mat, 16 * sizeof(float));
180 (*device)->set_context(*device);
181 glClearColor(0.0, 0.0, 0.0, 0.0);
182 glColor3f(1.0, 1.0, 1.0);
187 /* This is not the OpenGL UID */
191 /*******************************************************************************
192 * Common IDirect3DDevice2
195 static HRESULT WINAPI IDirect3DDevice2_QueryInterface(LPDIRECT3DDEVICE2 this,
201 WINE_StringFromCLSID((LPCLSID)riid,xrefiid);
202 FIXME(ddraw, "(%p)->(%s,%p): stub\n", this, xrefiid,ppvObj);
209 static ULONG WINAPI IDirect3DDevice2_AddRef(LPDIRECT3DDEVICE2 this)
211 TRACE(ddraw, "(%p)->()incrementing from %lu.\n", this, this->ref );
213 return ++(this->ref);
218 static ULONG WINAPI IDirect3DDevice2_Release(LPDIRECT3DDEVICE2 this)
220 FIXME( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
222 if (!--(this->ref)) {
223 HeapFree(GetProcessHeap(),0,this);
231 /*** IDirect3DDevice2 methods ***/
232 static HRESULT WINAPI IDirect3DDevice2_GetCaps(LPDIRECT3DDEVICE2 this,
233 LPD3DDEVICEDESC lpdescsoft,
234 LPD3DDEVICEDESC lpdeschard)
236 FIXME(ddraw, "(%p)->(%p,%p): stub\n", this, lpdescsoft, lpdeschard);
238 fill_opengl_caps(lpdescsoft, lpdeschard);
245 static HRESULT WINAPI IDirect3DDevice2_SwapTextureHandles(LPDIRECT3DDEVICE2 this,
246 LPDIRECT3DTEXTURE2 lptex1,
247 LPDIRECT3DTEXTURE2 lptex2)
249 FIXME(ddraw, "(%p)->(%p,%p): stub\n", this, lptex1, lptex2);
256 static HRESULT WINAPI IDirect3DDevice2_GetStats(LPDIRECT3DDEVICE2 this,
259 FIXME(ddraw, "(%p)->(%p): stub\n", this, lpstats);
266 static HRESULT WINAPI IDirect3DDevice2_AddViewport(LPDIRECT3DDEVICE2 this,
267 LPDIRECT3DVIEWPORT2 lpvp)
269 FIXME(ddraw, "(%p)->(%p): stub\n", this, lpvp);
271 /* Adds this viewport to the viewport list */
272 lpvp->next = this->viewport_list;
273 this->viewport_list = lpvp;
280 static HRESULT WINAPI IDirect3DDevice2_DeleteViewport(LPDIRECT3DDEVICE2 this,
281 LPDIRECT3DVIEWPORT2 lpvp)
283 LPDIRECT3DVIEWPORT2 cur, prev;
284 FIXME(ddraw, "(%p)->(%p): stub\n", this, lpvp);
286 /* Finds this viewport in the list */
288 cur = this->viewport_list;
289 while ((cur != NULL) && (cur != lpvp)) {
294 return DDERR_INVALIDOBJECT;
298 this->viewport_list = cur->next;
300 prev->next = cur->next;
307 static HRESULT WINAPI IDirect3DDevice2_NextViewport(LPDIRECT3DDEVICE2 this,
308 LPDIRECT3DVIEWPORT2 lpvp,
309 LPDIRECT3DVIEWPORT2* lplpvp,
312 FIXME(ddraw, "(%p)->(%p,%p,%08lx): stub\n", this, lpvp, lpvp, dwFlags);
316 *lplpvp = lpvp->next;
320 *lplpvp = this->viewport_list;
324 lpvp = this->viewport_list;
325 while (lpvp->next != NULL)
332 return DDERR_INVALIDPARAMS;
338 static HRESULT enum_texture_format_OpenGL(LPD3DENUMTEXTUREFORMATSCALLBACK cb,
341 LPDDPIXELFORMAT pformat;
343 /* Do the texture enumeration */
344 sdesc.dwSize = sizeof(DDSURFACEDESC);
345 sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
346 sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
347 pformat = &(sdesc.ddpfPixelFormat);
348 pformat->dwSize = sizeof(DDPIXELFORMAT);
349 pformat->dwFourCC = 0;
351 TRACE(ddraw, "Enumerating GL_RGBA unpacked (32)\n");
352 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
353 pformat->x.dwRGBBitCount = 32;
354 pformat->y.dwRBitMask = 0xFF000000;
355 pformat->z.dwGBitMask = 0x00FF0000;
356 pformat->xx.dwBBitMask = 0x0000FF00;
357 pformat->xy.dwRGBAlphaBitMask = 0x000000FF;
358 if (cb(&sdesc, context) == 0)
361 TRACE(ddraw, "Enumerating GL_RGB unpacked (24)\n");
362 pformat->dwFlags = DDPF_RGB;
363 pformat->x.dwRGBBitCount = 24;
364 pformat->y.dwRBitMask = 0x00FF0000;
365 pformat->z.dwGBitMask = 0x0000FF00;
366 pformat->xx.dwBBitMask = 0x000000FF;
367 pformat->xy.dwRGBAlphaBitMask = 0x00000000;
368 if (cb(&sdesc, context) == 0)
371 #ifndef HAVE_BUGGY_MESAGL
372 /* The packed texture format are buggy in Mesa. The bug was reported and corrected,
373 so that future version will work great. */
374 TRACE(ddraw, "Enumerating GL_RGB packed GL_UNSIGNED_SHORT_5_6_5 (16)\n");
375 pformat->dwFlags = DDPF_RGB;
376 pformat->x.dwRGBBitCount = 16;
377 pformat->y.dwRBitMask = 0x0000F800;
378 pformat->z.dwGBitMask = 0x000007E0;
379 pformat->xx.dwBBitMask = 0x0000001F;
380 pformat->xy.dwRGBAlphaBitMask = 0x00000000;
381 if (cb(&sdesc, context) == 0)
384 TRACE(ddraw, "Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_5_5_5_1 (16)\n");
385 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
386 pformat->x.dwRGBBitCount = 16;
387 pformat->y.dwRBitMask = 0x0000F800;
388 pformat->z.dwGBitMask = 0x000007C0;
389 pformat->xx.dwBBitMask = 0x0000003E;
390 pformat->xy.dwRGBAlphaBitMask = 0x00000001;
391 if (cb(&sdesc, context) == 0)
394 TRACE(ddraw, "Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_4_4_4_4 (16)\n");
395 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
396 pformat->x.dwRGBBitCount = 16;
397 pformat->y.dwRBitMask = 0x0000F000;
398 pformat->z.dwGBitMask = 0x00000F00;
399 pformat->xx.dwBBitMask = 0x000000F0;
400 pformat->xy.dwRGBAlphaBitMask = 0x0000000F;
401 if (cb(&sdesc, context) == 0)
404 TRACE(ddraw, "Enumerating GL_RGB packed GL_UNSIGNED_BYTE_3_3_2 (8)\n");
405 pformat->dwFlags = DDPF_RGB;
406 pformat->x.dwRGBBitCount = 8;
407 pformat->y.dwRBitMask = 0x0000F800;
408 pformat->z.dwGBitMask = 0x000007C0;
409 pformat->xx.dwBBitMask = 0x0000003E;
410 pformat->xy.dwRGBAlphaBitMask = 0x00000001;
411 if (cb(&sdesc, context) == 0)
415 TRACE(ddraw, "Enumerating Paletted (8)\n");
416 pformat->dwFlags = DDPF_PALETTEINDEXED8;
417 pformat->x.dwRGBBitCount = 8;
418 pformat->y.dwRBitMask = 0x00000000;
419 pformat->z.dwGBitMask = 0x00000000;
420 pformat->xx.dwBBitMask = 0x00000000;
421 pformat->xy.dwRGBAlphaBitMask = 0x00000000;
422 if (cb(&sdesc, context) == 0)
425 TRACE(ddraw, "End of enumeration\n");
430 static HRESULT WINAPI IDirect3DDevice2_EnumTextureFormats(LPDIRECT3DDEVICE2 this,
431 LPD3DENUMTEXTUREFORMATSCALLBACK cb,
434 FIXME(ddraw, "(%p)->(%p,%p): stub\n", this, cb, context);
436 return enum_texture_format_OpenGL(cb, context);
441 static HRESULT WINAPI IDirect3DDevice2_BeginScene(LPDIRECT3DDEVICE2 this)
443 /* OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) this; */
445 FIXME(ddraw, "(%p)->(): stub\n", this);
447 /* Here, we should get the DDraw surface and 'copy it' to the
448 OpenGL surface.... */
455 static HRESULT WINAPI IDirect3DDevice2_EndScene(LPDIRECT3DDEVICE2 this)
457 OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) this;
458 LPDIRECTDRAWSURFACE3 surf = (LPDIRECTDRAWSURFACE3) this->surface;
462 unsigned short *dest;
464 FIXME(ddraw, "(%p)->(): stub\n", this);
466 /* Here we copy back the OpenGL scene to the the DDraw surface */
467 /* First, lock the surface */
468 surf->lpvtbl->fnLock(surf,NULL,&sdesc,DDLOCK_WRITEONLY,0);
470 /* The copy the OpenGL buffer to this surface */
472 /* NOTE : this is only for debugging purpose. I KNOW it is really unoptimal.
473 I am currently working on a set of patches for Mesa to have OSMesa support
474 16 bpp surfaces => we will able to render directly onto the surface, no
475 need to do a bpp conversion */
476 dest = (unsigned short *) sdesc.y.lpSurface;
477 src = ((unsigned char *) odev->buffer) + 4 * (sdesc.dwWidth * (sdesc.dwHeight - 1));
478 for (y = 0; y < sdesc.dwHeight; y++) {
479 unsigned char *lsrc = src;
481 for (x = 0; x < sdesc.dwWidth ; x++) {
482 unsigned char r = *lsrc++;
483 unsigned char g = *lsrc++;
484 unsigned char b = *lsrc++;
486 *dest = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
491 src -= 4 * sdesc.dwWidth;
494 /* Unlock the surface */
495 surf->lpvtbl->fnUnlock(surf,sdesc.y.lpSurface);
502 static HRESULT WINAPI IDirect3DDevice2_GetDirect3D(LPDIRECT3DDEVICE2 this, LPDIRECT3D2 *lpd3d2)
504 TRACE(ddraw, "(%p)->(%p): stub\n", this, lpd3d2);
513 /*** DrawPrimitive API ***/
514 static HRESULT WINAPI IDirect3DDevice2_SetCurrentViewport(LPDIRECT3DDEVICE2 this,
515 LPDIRECT3DVIEWPORT2 lpvp)
517 FIXME(ddraw, "(%p)->(%p): stub\n", this, lpvp);
519 /* Should check if the viewport was added or not */
521 /* Set this viewport as the current viewport */
522 this->current_viewport = lpvp;
524 /* Activate this viewport */
525 lpvp->device.active_device2 = this;
526 lpvp->activate(lpvp);
533 static HRESULT WINAPI IDirect3DDevice2_GetCurrentViewport(LPDIRECT3DDEVICE2 this,
534 LPDIRECT3DVIEWPORT2 *lplpvp)
536 FIXME(ddraw, "(%p)->(%p): stub\n", this, lplpvp);
538 /* Returns the current viewport */
539 *lplpvp = this->current_viewport;
546 static HRESULT WINAPI IDirect3DDevice2_SetRenderTarget(LPDIRECT3DDEVICE2 this,
547 LPDIRECTDRAWSURFACE lpdds,
550 FIXME(ddraw, "(%p)->(%p,%08lx): stub\n", this, lpdds, dwFlags);
557 static HRESULT WINAPI IDirect3DDevice2_GetRenderTarget(LPDIRECT3DDEVICE2 this,
558 LPDIRECTDRAWSURFACE *lplpdds)
560 FIXME(ddraw, "(%p)->(%p): stub\n", this, lplpdds);
562 /* Returns the current rendering target (the surface on wich we render) */
563 *lplpdds = this->surface;
570 static HRESULT WINAPI IDirect3DDevice2_Begin(LPDIRECT3DDEVICE2 this,
571 D3DPRIMITIVETYPE d3dp,
575 FIXME(ddraw, "(%p)->(%d,%d,%08lx): stub\n", this, d3dp, d3dv, dwFlags);
582 static HRESULT WINAPI IDirect3DDevice2_BeginIndexed(LPDIRECT3DDEVICE2 this,
583 D3DPRIMITIVETYPE d3dp,
589 FIXME(ddraw, "(%p)->(%d,%d,%p,%ld,%08lx): stub\n", this, d3dp, d3dv, lpvert, numvert, dwFlags);
596 static HRESULT WINAPI IDirect3DDevice2_Vertex(LPDIRECT3DDEVICE2 this,
599 FIXME(ddraw, "(%p)->(%p): stub\n", this, lpvert);
606 static HRESULT WINAPI IDirect3DDevice2_Index(LPDIRECT3DDEVICE2 this,
609 FIXME(ddraw, "(%p)->(%d): stub\n", this, index);
616 static HRESULT WINAPI IDirect3DDevice2_End(LPDIRECT3DDEVICE2 this,
619 FIXME(ddraw, "(%p)->(%08lx): stub\n", this, dwFlags);
627 static HRESULT WINAPI IDirect3DDevice2_GetRenderState(LPDIRECT3DDEVICE2 this,
628 D3DRENDERSTATETYPE d3drs,
631 FIXME(ddraw, "(%p)->(%d,%p): stub\n", this, d3drs, lprstate);
638 static HRESULT WINAPI IDirect3DDevice2_SetRenderState(LPDIRECT3DDEVICE2 this,
639 D3DRENDERSTATETYPE dwRenderStateType,
642 OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) this;
644 TRACE(ddraw, "(%p)->(%d,%ld)\n", this, dwRenderStateType, dwRenderState);
646 /* Call the render state functions */
647 set_render_state(dwRenderStateType, dwRenderState, &(odev->rs));
654 static HRESULT WINAPI IDirect3DDevice2_GetLightState(LPDIRECT3DDEVICE2 this,
655 D3DLIGHTSTATETYPE d3dls,
658 FIXME(ddraw, "(%p)->(%d,%p): stub\n", this, d3dls, lplstate);
665 static HRESULT WINAPI IDirect3DDevice2_SetLightState(LPDIRECT3DDEVICE2 this,
666 D3DLIGHTSTATETYPE dwLightStateType,
669 FIXME(ddraw, "(%p)->(%d,%08lx): stub\n", this, dwLightStateType, dwLightState);
671 switch (dwLightStateType) {
672 case D3DLIGHTSTATE_MATERIAL: { /* 1 */
673 LPDIRECT3DMATERIAL2 mat = (LPDIRECT3DMATERIAL2) dwLightState;
678 TRACE(ddraw, "Zoups !!!\n");
682 case D3DLIGHTSTATE_AMBIENT: { /* 2 */
685 light[0] = ((dwLightState >> 16) & 0xFF) / 255.0;
686 light[1] = ((dwLightState >> 8) & 0xFF) / 255.0;
687 light[2] = ((dwLightState >> 0) & 0xFF) / 255.0;
689 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (float *) light);
692 case D3DLIGHTSTATE_COLORMODEL: /* 3 */
695 case D3DLIGHTSTATE_FOGMODE: /* 4 */
698 case D3DLIGHTSTATE_FOGSTART: /* 5 */
701 case D3DLIGHTSTATE_FOGEND: /* 6 */
704 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */
708 TRACE(ddraw, "Unexpected Light State Type\n");
709 return DDERR_INVALIDPARAMS;
717 static HRESULT WINAPI IDirect3DDevice2_SetTransform(LPDIRECT3DDEVICE2 this,
718 D3DTRANSFORMSTATETYPE d3dts,
719 LPD3DMATRIX lpmatrix)
721 OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) this;
723 FIXME(ddraw, "(%p)->(%d,%p): stub\n", this, d3dts, lpmatrix);
725 /* Using a trial and failure approach, I found that the order of
726 Direct3D transformations that works best is :
728 ScreenCoord = ProjectionMat * ViewMat * WorldMat * ObjectCoord
730 As OpenGL uses only two matrices, I combined PROJECTION and VIEW into
731 OpenGL's GL_PROJECTION matrix and the WORLD into GL_MODELVIEW.
733 If anyone has a good explanation of the three different matrices in
734 the SDK online documentation, feel free to point it to me. For example,
735 which matrices transform lights ? In OpenGL only the PROJECTION matrix
736 transform the lights, not the MODELVIEW. Using the matrix names, I
737 supposed that PROJECTION and VIEW (all 'camera' related names) do
738 transform lights, but WORLD do not. It may be wrong though... */
740 /* After reading through both OpenGL and Direct3D documentations, I
741 thought that D3D matrices were written in 'line major mode' transposed
742 from OpenGL's 'column major mode'. But I found out that a simple memcpy
743 works fine to transfer one matrix format to the other (it did not work
744 when transposing)....
747 1) are the documentations wrong
748 2) does the matrix work even if they are not read correctly
749 3) is Mesa's implementation of OpenGL not compliant regarding Matrix
750 loading using glLoadMatrix ?
752 Anyway, I always use 'conv_mat' to transfer the matrices from one format
753 to the other so that if I ever find out that I need to transpose them, I
754 will able to do it quickly, only by changing the macro conv_mat. */
757 case D3DTRANSFORMSTATE_WORLD: {
758 conv_mat(lpmatrix, odev->world_mat);
759 glMatrixMode(GL_MODELVIEW);
760 glLoadMatrixf((float *) &(odev->world_mat));
763 case D3DTRANSFORMSTATE_VIEW: {
764 conv_mat(lpmatrix, odev->view_mat);
765 glMatrixMode(GL_PROJECTION);
766 glLoadMatrixf((float *) &(odev->proj_mat));
767 glMultMatrixf((float *) &(odev->view_mat));
770 case D3DTRANSFORMSTATE_PROJECTION: {
771 conv_mat(lpmatrix, odev->proj_mat);
772 glMatrixMode(GL_PROJECTION);
773 glLoadMatrixf((float *) &(odev->proj_mat));
774 glMultMatrixf((float *) &(odev->view_mat));
786 static HRESULT WINAPI IDirect3DDevice2_GetTransform(LPDIRECT3DDEVICE2 this,
787 D3DTRANSFORMSTATETYPE d3dts,
788 LPD3DMATRIX lpmatrix)
790 FIXME(ddraw, "(%p)->(%d,%p): stub\n", this, d3dts, lpmatrix);
797 static HRESULT WINAPI IDirect3DDevice2_MultiplyTransform(LPDIRECT3DDEVICE2 this,
798 D3DTRANSFORMSTATETYPE d3dts,
799 LPD3DMATRIX lpmatrix)
801 FIXME(ddraw, "(%p)->(%d,%p): stub\n", this, d3dts, lpmatrix);
806 #define DRAW_PRIMITIVE(MAXVERT,INDEX) \
807 /* Puts GL in the correct lighting mode */ \
808 if (odev->vt != d3dv) { \
809 if (odev->vt == D3DVT_TLVERTEX) { \
810 /* Need to put the correct transformation again */ \
811 glMatrixMode(GL_MODELVIEW); \
812 glLoadMatrixf((float *) &(odev->world_mat)); \
813 glMatrixMode(GL_PROJECTION); \
814 glLoadMatrixf((float *) &(odev->proj_mat)); \
815 glMultMatrixf((float *) &(odev->view_mat)); \
820 TRACE(ddraw, "Standard Vertex\n"); \
821 glEnable(GL_LIGHTING); \
824 case D3DVT_LVERTEX: \
825 TRACE(ddraw, "Lighted Vertex\n"); \
826 glDisable(GL_LIGHTING); \
829 case D3DVT_TLVERTEX: { \
830 GLdouble height, width, minZ, maxZ; \
832 TRACE(ddraw, "Transformed - Lighted Vertex\n"); \
833 /* First, disable lighting */ \
834 glDisable(GL_LIGHTING); \
836 /* Then do not put any transformation matrixes */ \
837 glMatrixMode(GL_MODELVIEW); \
839 glMatrixMode(GL_PROJECTION); \
842 if (this->current_viewport == NULL) { \
843 ERR(ddraw, "No current viewport !\n"); \
844 /* Using standard values */ \
850 if (this->current_viewport->use_vp2) { \
851 height = (GLdouble) this->current_viewport->viewport.vp2.dwHeight; \
852 width = (GLdouble) this->current_viewport->viewport.vp2.dwWidth; \
853 minZ = (GLdouble) this->current_viewport->viewport.vp2.dvMinZ; \
854 maxZ = (GLdouble) this->current_viewport->viewport.vp2.dvMaxZ; \
856 height = (GLdouble) this->current_viewport->viewport.vp1.dwHeight; \
857 width = (GLdouble) this->current_viewport->viewport.vp1.dwWidth; \
858 minZ = (GLdouble) this->current_viewport->viewport.vp1.dvMinZ; \
859 maxZ = (GLdouble) this->current_viewport->viewport.vp1.dvMaxZ; \
863 glOrtho(0.0, width, height, 0.0, -minZ, -maxZ); \
867 ERR(ddraw, "Unhandled vertex type\n"); \
875 case D3DPT_POINTLIST: \
876 TRACE(ddraw, "Start POINTS\n"); \
877 glBegin(GL_POINTS); \
880 case D3DPT_LINELIST: \
881 TRACE(ddraw, "Start LINES\n"); \
885 case D3DPT_LINESTRIP: \
886 TRACE(ddraw, "Start LINE_STRIP\n"); \
887 glBegin(GL_LINE_STRIP); \
890 case D3DPT_TRIANGLELIST: \
891 TRACE(ddraw, "Start TRIANGLES\n"); \
892 glBegin(GL_TRIANGLES); \
895 case D3DPT_TRIANGLESTRIP: \
896 TRACE(ddraw, "Start TRIANGLE_STRIP\n"); \
897 glBegin(GL_TRIANGLE_STRIP); \
900 case D3DPT_TRIANGLEFAN: \
901 TRACE(ddraw, "Start TRIANGLE_FAN\n"); \
902 glBegin(GL_TRIANGLE_FAN); \
906 TRACE(ddraw, "Unhandled primitive\n"); \
910 /* Draw the primitives */ \
911 for (vx_index = 0; vx_index < MAXVERT; vx_index++) { \
913 case D3DVT_VERTEX: { \
914 D3DVERTEX *vx = ((D3DVERTEX *) lpvertex) + INDEX; \
916 glNormal3f(vx->nx.nx, vx->ny.ny, vx->nz.nz); \
917 glVertex3f(vx->x.x, vx->y.y, vx->z.z); \
918 TRACE(ddraw, " V: %f %f %f\n", vx->x.x, vx->y.y, vx->z.z); \
921 case D3DVT_LVERTEX: { \
922 D3DLVERTEX *vx = ((D3DLVERTEX *) lpvertex) + INDEX; \
923 DWORD col = vx->c.color; \
925 glColor3f(((col >> 16) & 0xFF) / 255.0, \
926 ((col >> 8) & 0xFF) / 255.0, \
927 ((col >> 0) & 0xFF) / 255.0); \
928 glVertex3f(vx->x.x, vx->y.y, vx->z.z); \
929 TRACE(ddraw, " LV: %f %f %f (%02lx %02lx %02lx)\n", \
930 vx->x.x, vx->y.y, vx->z.z, \
931 ((col >> 16) & 0xFF), ((col >> 8) & 0xFF), ((col >> 0) & 0xFF)); \
934 case D3DVT_TLVERTEX: { \
935 D3DTLVERTEX *vx = ((D3DTLVERTEX *) lpvertex) + INDEX; \
936 DWORD col = vx->c.color; \
938 glColor3f(((col >> 16) & 0xFF) / 255.0, \
939 ((col >> 8) & 0xFF) / 255.0, \
940 ((col >> 0) & 0xFF) / 255.0); \
941 glTexCoord2f(vx->u.tu, vx->v.tv); \
942 if (vx->r.rhw < 0.01) \
943 glVertex3f(vx->x.sx, \
947 glVertex4f(vx->x.sx / vx->r.rhw, \
948 vx->y.sy / vx->r.rhw, \
949 vx->z.sz / vx->r.rhw, \
951 TRACE(ddraw, " TLV: %f %f %f (%02lx %02lx %02lx) (%f %f) (%f)\n", \
952 vx->x.sx, vx->y.sy, vx->z.sz, \
953 ((col >> 16) & 0xFF), ((col >> 8) & 0xFF), ((col >> 0) & 0xFF), \
954 vx->u.tu, vx->v.tv, vx->r.rhw); \
958 TRACE(ddraw, "Unhandled vertex type\n"); \
964 TRACE(ddraw, "End\n");
967 static HRESULT WINAPI IDirect3DDevice2_DrawPrimitive(LPDIRECT3DDEVICE2 this,
968 D3DPRIMITIVETYPE d3dp,
974 OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) this;
977 TRACE(ddraw, "(%p)->(%d,%d,%p,%ld,%08lx): stub\n", this, d3dp, d3dv, lpvertex, vertcount, dwFlags);
979 DRAW_PRIMITIVE(vertcount, vx_index);
986 static HRESULT WINAPI IDirect3DDevice2_DrawIndexedPrimitive(LPDIRECT3DDEVICE2 this,
987 D3DPRIMITIVETYPE d3dp,
995 OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) this;
998 TRACE(ddraw, "(%p)->(%d,%d,%p,%ld,%p,%ld,%08lx): stub\n", this, d3dp, d3dv, lpvertex, vertcount, lpindexes, indexcount, dwFlags);
1000 DRAW_PRIMITIVE(indexcount, lpindexes[vx_index]);
1007 static HRESULT WINAPI IDirect3DDevice2_SetClipStatus(LPDIRECT3DDEVICE2 this,
1008 LPD3DCLIPSTATUS lpcs)
1010 FIXME(ddraw, "(%p)->(%p): stub\n", this, lpcs);
1017 static HRESULT WINAPI IDirect3DDevice2_GetClipStatus(LPDIRECT3DDEVICE2 this,
1018 LPD3DCLIPSTATUS lpcs)
1020 FIXME(ddraw, "(%p)->(%p): stub\n", this, lpcs);
1027 /*******************************************************************************
1028 * OpenGL-specific IDirect3DDevice2
1031 /*******************************************************************************
1032 * OpenGL-specific VTable
1035 static IDirect3DDevice2_VTable OpenGL_vtable = {
1036 IDirect3DDevice2_QueryInterface,
1037 IDirect3DDevice2_AddRef,
1038 IDirect3DDevice2_Release,
1039 /*** IDirect3DDevice2 methods ***/
1040 IDirect3DDevice2_GetCaps,
1041 IDirect3DDevice2_SwapTextureHandles,
1042 IDirect3DDevice2_GetStats,
1043 IDirect3DDevice2_AddViewport,
1044 IDirect3DDevice2_DeleteViewport,
1045 IDirect3DDevice2_NextViewport,
1046 IDirect3DDevice2_EnumTextureFormats,
1047 IDirect3DDevice2_BeginScene,
1048 IDirect3DDevice2_EndScene,
1049 IDirect3DDevice2_GetDirect3D,
1051 /*** DrawPrimitive API ***/
1052 IDirect3DDevice2_SetCurrentViewport,
1053 IDirect3DDevice2_GetCurrentViewport,
1055 IDirect3DDevice2_SetRenderTarget,
1056 IDirect3DDevice2_GetRenderTarget,
1058 IDirect3DDevice2_Begin,
1059 IDirect3DDevice2_BeginIndexed,
1060 IDirect3DDevice2_Vertex,
1061 IDirect3DDevice2_Index,
1062 IDirect3DDevice2_End,
1064 IDirect3DDevice2_GetRenderState,
1065 IDirect3DDevice2_SetRenderState,
1066 IDirect3DDevice2_GetLightState,
1067 IDirect3DDevice2_SetLightState,
1068 IDirect3DDevice2_SetTransform,
1069 IDirect3DDevice2_GetTransform,
1070 IDirect3DDevice2_MultiplyTransform,
1072 IDirect3DDevice2_DrawPrimitive,
1073 IDirect3DDevice2_DrawIndexedPrimitive,
1075 IDirect3DDevice2_SetClipStatus,
1076 IDirect3DDevice2_GetClipStatus,
1079 /*******************************************************************************
1082 int d3d_OpenGL_dx3(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) {
1083 D3DDEVICEDESC d1,d2;
1085 TRACE(ddraw," Enumerating OpenGL D3D device.\n");
1087 fill_opengl_caps(&d1, &d2);
1089 return cb((void*)&IID_D3DDEVICE_OpenGL,"WINE Direct3D using OpenGL","direct3d",&d1,&d2,context);
1092 float id_mat[16] = {
1099 int is_OpenGL_dx3(REFCLSID rguid, LPDIRECTDRAWSURFACE surface, LPDIRECT3DDEVICE *device)
1101 if (!memcmp(&IID_D3DDEVICE_OpenGL,rguid,sizeof(IID_D3DDEVICE_OpenGL))) {
1102 OpenGL_IDirect3DDevice *odev;
1104 *device = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(OpenGL_IDirect3DDevice));
1105 odev = (OpenGL_IDirect3DDevice *) (*device);
1107 (*device)->lpvtbl = &OpenGL_vtable_dx3;
1108 (*device)->d3d = NULL;
1109 (*device)->surface = surface;
1111 (*device)->viewport_list = NULL;
1112 (*device)->current_viewport = NULL;
1114 (*device)->set_context = set_context_dx3;
1116 TRACE(ddraw, "OpenGL device created \n");
1118 /* Create the OpenGL context */
1119 odev->ctx = OSMesaCreateContext(OSMESA_RGBA, NULL);
1120 odev->buffer = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
1121 surface->s.surface_desc.dwWidth * surface->s.surface_desc.dwHeight * 4);
1122 odev->rs.src = GL_ONE;
1123 odev->rs.dst = GL_ZERO;
1124 odev->rs.mag = GL_NEAREST;
1125 odev->rs.min = GL_NEAREST;
1127 odev->world_mat = (LPD3DMATRIX) &id_mat;
1128 odev->view_mat = (LPD3DMATRIX) &id_mat;
1129 odev->proj_mat = (LPD3DMATRIX) &id_mat;
1131 /* Initialisation */
1132 (*device)->set_context(*device);
1133 glClearColor(0.0, 0.0, 0.0, 0.0);
1134 glColor3f(1.0, 1.0, 1.0);
1139 /* This is not the OpenGL UID */
1144 /*******************************************************************************
1147 static HRESULT WINAPI IDirect3DDevice_QueryInterface(LPDIRECT3DDEVICE this,
1153 WINE_StringFromCLSID((LPCLSID)riid,xrefiid);
1154 FIXME(ddraw, "(%p)->(%s,%p): stub\n", this, xrefiid,ppvObj);
1161 static ULONG WINAPI IDirect3DDevice_AddRef(LPDIRECT3DDEVICE this)
1163 TRACE(ddraw, "(%p)->()incrementing from %lu.\n", this, this->ref );
1165 return ++(this->ref);
1170 static ULONG WINAPI IDirect3DDevice_Release(LPDIRECT3DDEVICE this)
1172 FIXME( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1174 if (!--(this->ref)) {
1175 HeapFree(GetProcessHeap(),0,this);
1182 static HRESULT WINAPI IDirect3DDevice_Initialize(LPDIRECT3DDEVICE this,
1185 LPD3DDEVICEDESC lpd3ddvdesc)
1187 TRACE(ddraw, "(%p)->(%p,%p,%p): stub\n", this, lpd3d,lpGUID, lpd3ddvdesc);
1189 return DDERR_ALREADYINITIALIZED;
1193 static HRESULT WINAPI IDirect3DDevice_GetCaps(LPDIRECT3DDEVICE this,
1194 LPD3DDEVICEDESC lpD3DHWDevDesc,
1195 LPD3DDEVICEDESC lpD3DSWDevDesc)
1197 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpD3DHWDevDesc, lpD3DSWDevDesc);
1199 fill_opengl_caps(lpD3DHWDevDesc, lpD3DSWDevDesc);
1205 static HRESULT WINAPI IDirect3DDevice_SwapTextureHandles(LPDIRECT3DDEVICE this,
1206 LPDIRECT3DTEXTURE lpD3DTex1,
1207 LPDIRECT3DTEXTURE lpD3DTex2)
1209 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpD3DTex1, lpD3DTex2);
1214 static HRESULT WINAPI IDirect3DDevice_CreateExecuteBuffer(LPDIRECT3DDEVICE this,
1215 LPD3DEXECUTEBUFFERDESC lpDesc,
1216 LPDIRECT3DEXECUTEBUFFER *lplpDirect3DExecuteBuffer,
1217 IUnknown *pUnkOuter)
1219 TRACE(ddraw, "(%p)->(%p,%p,%p)\n", this, lpDesc, lplpDirect3DExecuteBuffer, pUnkOuter);
1221 *lplpDirect3DExecuteBuffer = d3dexecutebuffer_create(this, lpDesc);
1227 static HRESULT WINAPI IDirect3DDevice_GetStats(LPDIRECT3DDEVICE this,
1228 LPD3DSTATS lpD3DStats)
1230 TRACE(ddraw, "(%p)->(%p): stub\n", this, lpD3DStats);
1236 static HRESULT WINAPI IDirect3DDevice_Execute(LPDIRECT3DDEVICE this,
1237 LPDIRECT3DEXECUTEBUFFER lpDirect3DExecuteBuffer,
1238 LPDIRECT3DVIEWPORT lpDirect3DViewport,
1241 TRACE(ddraw, "(%p)->(%p,%p,%08ld): stub\n", this, lpDirect3DExecuteBuffer, lpDirect3DViewport, dwFlags);
1243 /* Put this as the default context */
1246 lpDirect3DExecuteBuffer->execute(lpDirect3DExecuteBuffer, this, lpDirect3DViewport);
1251 static HRESULT WINAPI IDirect3DDevice_AddViewport(LPDIRECT3DDEVICE this,
1252 LPDIRECT3DVIEWPORT lpvp)
1254 FIXME(ddraw, "(%p)->(%p): stub\n", this, lpvp);
1256 /* Adds this viewport to the viewport list */
1257 lpvp->next = this->viewport_list;
1258 this->viewport_list = lpvp;
1265 static HRESULT WINAPI IDirect3DDevice_DeleteViewport(LPDIRECT3DDEVICE this,
1266 LPDIRECT3DVIEWPORT lpvp)
1268 LPDIRECT3DVIEWPORT cur, prev;
1269 FIXME(ddraw, "(%p)->(%p): stub\n", this, lpvp);
1271 /* Finds this viewport in the list */
1273 cur = this->viewport_list;
1274 while ((cur != NULL) && (cur != lpvp)) {
1279 return DDERR_INVALIDOBJECT;
1283 this->viewport_list = cur->next;
1285 prev->next = cur->next;
1292 static HRESULT WINAPI IDirect3DDevice_NextViewport(LPDIRECT3DDEVICE this,
1293 LPDIRECT3DVIEWPORT lpvp,
1294 LPDIRECT3DVIEWPORT* lplpvp,
1297 FIXME(ddraw, "(%p)->(%p,%p,%08lx): stub\n", this, lpvp, lpvp, dwFlags);
1301 *lplpvp = lpvp->next;
1305 *lplpvp = this->viewport_list;
1309 lpvp = this->viewport_list;
1310 while (lpvp->next != NULL)
1317 return DDERR_INVALIDPARAMS;
1323 static HRESULT WINAPI IDirect3DDevice_Pick(LPDIRECT3DDEVICE this,
1324 LPDIRECT3DEXECUTEBUFFER lpDirect3DExecuteBuffer,
1325 LPDIRECT3DVIEWPORT lpDirect3DViewport,
1329 TRACE(ddraw, "(%p)->(%p,%p,%08lx,%p): stub\n", this, lpDirect3DExecuteBuffer, lpDirect3DViewport,
1336 static HRESULT WINAPI IDirect3DDevice_GetPickRecords(LPDIRECT3DDEVICE this,
1338 LPD3DPICKRECORD lpD3DPickRec)
1340 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpCount, lpD3DPickRec);
1346 static HRESULT WINAPI IDirect3DDevice_EnumTextureFormats(LPDIRECT3DDEVICE this,
1347 LPD3DENUMTEXTUREFORMATSCALLBACK lpd3dEnumTextureProc,
1350 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpd3dEnumTextureProc, lpArg);
1352 return enum_texture_format_OpenGL(lpd3dEnumTextureProc, lpArg);
1356 static HRESULT WINAPI IDirect3DDevice_CreateMatrix(LPDIRECT3DDEVICE this,
1357 LPD3DMATRIXHANDLE lpD3DMatHandle)
1359 TRACE(ddraw, "(%p)->(%p)\n", this, lpD3DMatHandle);
1361 *lpD3DMatHandle = (D3DMATRIXHANDLE) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(D3DMATRIX));
1367 static HRESULT WINAPI IDirect3DDevice_SetMatrix(LPDIRECT3DDEVICE this,
1368 D3DMATRIXHANDLE d3dMatHandle,
1369 const LPD3DMATRIX lpD3DMatrix)
1371 TRACE(ddraw, "(%p)->(%08lx,%p)\n", this, d3dMatHandle, lpD3DMatrix);
1373 dump_mat(lpD3DMatrix);
1375 *((D3DMATRIX *) d3dMatHandle) = *lpD3DMatrix;
1381 static HRESULT WINAPI IDirect3DDevice_GetMatrix(LPDIRECT3DDEVICE this,
1382 D3DMATRIXHANDLE D3DMatHandle,
1383 LPD3DMATRIX lpD3DMatrix)
1385 TRACE(ddraw, "(%p)->(%08lx,%p)\n", this, D3DMatHandle, lpD3DMatrix);
1387 *lpD3DMatrix = *((D3DMATRIX *) D3DMatHandle);
1393 static HRESULT WINAPI IDirect3DDevice_DeleteMatrix(LPDIRECT3DDEVICE this,
1394 D3DMATRIXHANDLE d3dMatHandle)
1396 TRACE(ddraw, "(%p)->(%08lx)\n", this, d3dMatHandle);
1398 HeapFree(GetProcessHeap(),0, (void *) d3dMatHandle);
1404 static HRESULT WINAPI IDirect3DDevice_BeginScene(LPDIRECT3DDEVICE this)
1406 /* OpenGL_IDirect3DDevice *odev = (OpenGL_IDirect3DDevice *) this; */
1408 FIXME(ddraw, "(%p)->(): stub\n", this);
1410 /* We get the pointer to the surface (should be done on flip) */
1411 /* odev->zb->pbuf = this->surface->s.surface_desc.y.lpSurface; */
1417 /* This is for the moment copy-pasted from IDirect3DDevice2...
1418 Will make a common function ... */
1419 static HRESULT WINAPI IDirect3DDevice_EndScene(LPDIRECT3DDEVICE this)
1421 OpenGL_IDirect3DDevice *odev = (OpenGL_IDirect3DDevice *) this;
1422 LPDIRECTDRAWSURFACE3 surf = (LPDIRECTDRAWSURFACE3) this->surface;
1423 DDSURFACEDESC sdesc;
1426 unsigned short *dest;
1428 FIXME(ddraw, "(%p)->(): stub\n", this);
1430 /* Here we copy back the OpenGL scene to the the DDraw surface */
1431 /* First, lock the surface */
1432 surf->lpvtbl->fnLock(surf,NULL,&sdesc,DDLOCK_WRITEONLY,0);
1434 /* The copy the OpenGL buffer to this surface */
1436 /* NOTE : this is only for debugging purpose. I KNOW it is really unoptimal.
1437 I am currently working on a set of patches for Mesa to have OSMesa support
1438 16 bpp surfaces => we will able to render directly onto the surface, no
1439 need to do a bpp conversion */
1440 dest = (unsigned short *) sdesc.y.lpSurface;
1441 src = ((unsigned char *) odev->buffer) + 4 * (sdesc.dwWidth * (sdesc.dwHeight - 1));
1442 for (y = 0; y < sdesc.dwHeight; y++) {
1443 unsigned char *lsrc = src;
1445 for (x = 0; x < sdesc.dwWidth ; x++) {
1446 unsigned char r = *lsrc++;
1447 unsigned char g = *lsrc++;
1448 unsigned char b = *lsrc++;
1451 *dest = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
1456 src -= 4 * sdesc.dwWidth;
1459 /* Unlock the surface */
1460 surf->lpvtbl->fnUnlock(surf,sdesc.y.lpSurface);
1466 static HRESULT WINAPI IDirect3DDevice_GetDirect3D(LPDIRECT3DDEVICE this,
1467 LPDIRECT3D *lpDirect3D)
1469 TRACE(ddraw, "(%p)->(%p): stub\n", this, lpDirect3D);
1476 /*******************************************************************************
1477 * Direct3DDevice VTable
1479 static IDirect3DDevice_VTable OpenGL_vtable_dx3 = {
1480 IDirect3DDevice_QueryInterface,
1481 IDirect3DDevice_AddRef,
1482 IDirect3DDevice_Release,
1483 IDirect3DDevice_Initialize,
1484 IDirect3DDevice_GetCaps,
1485 IDirect3DDevice_SwapTextureHandles,
1486 IDirect3DDevice_CreateExecuteBuffer,
1487 IDirect3DDevice_GetStats,
1488 IDirect3DDevice_Execute,
1489 IDirect3DDevice_AddViewport,
1490 IDirect3DDevice_DeleteViewport,
1491 IDirect3DDevice_NextViewport,
1492 IDirect3DDevice_Pick,
1493 IDirect3DDevice_GetPickRecords,
1494 IDirect3DDevice_EnumTextureFormats,
1495 IDirect3DDevice_CreateMatrix,
1496 IDirect3DDevice_SetMatrix,
1497 IDirect3DDevice_GetMatrix,
1498 IDirect3DDevice_DeleteMatrix,
1499 IDirect3DDevice_BeginScene,
1500 IDirect3DDevice_EndScene,
1501 IDirect3DDevice_GetDirect3D,
1504 #else /* HAVE_MESAGL */
1506 int d3d_OpenGL(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) {
1510 int is_OpenGL(REFCLSID rguid, LPDIRECTDRAWSURFACE surface, LPDIRECT3DDEVICE2 *device, LPDIRECT3D2 d3d)
1515 int d3d_OpenGL_dx3(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) {
1519 int is_OpenGL_dx3(REFCLSID rguid, LPDIRECTDRAWSURFACE surface, LPDIRECT3DDEVICE *device)
1524 #endif /* HAVE_MESAGL */