4 This files contains all the D3D devices that Wine supports. For the moment
5 only the 'OpenGL' target is supported. */
11 #include "wine/obj_base.h"
17 #include "d3d_private.h"
19 /* Define this variable if you have an unpatched Mesa 3.0 (patches are available
20 on Mesa's home page) or version 3.1b.
22 Version 3.2b should correct this bug */
23 #undef HAVE_BUGGY_MESAGL
27 static GUID IID_D3DDEVICE2_OpenGL = {
31 { 0x8b,0x7c,0x0e,0x4e,0xd8,0x3c,0x2b,0x3c }
34 static GUID IID_D3DDEVICE_OpenGL = {
38 { 0x82,0x2d,0xa8,0xd5,0x31,0x87,0xca,0xfa }
42 static IDirect3DDevice2_VTable OpenGL_vtable;
43 static IDirect3DDevice_VTable OpenGL_vtable_dx3;
45 /*******************************************************************************
46 * OpenGL static functions
48 static void set_context(LPDIRECT3DDEVICE2 this) {
49 OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) this;
51 OSMesaMakeCurrent(odev->ctx, odev->buffer,
53 this->surface->s.surface_desc.dwWidth,
54 this->surface->s.surface_desc.dwHeight);
57 static void set_context_dx3(LPDIRECT3DDEVICE this) {
58 OpenGL_IDirect3DDevice *odev = (OpenGL_IDirect3DDevice *) this;
60 OSMesaMakeCurrent(odev->ctx, odev->buffer,
62 this->surface->s.surface_desc.dwWidth,
63 this->surface->s.surface_desc.dwHeight);
66 static void fill_opengl_primcaps(D3DPRIMCAPS *pc)
68 pc->dwSize = sizeof(*pc);
69 pc->dwMiscCaps = D3DPMISCCAPS_CONFORMANT | D3DPMISCCAPS_CULLCCW | D3DPMISCCAPS_CULLCW |
70 D3DPMISCCAPS_LINEPATTERNREP | D3DPMISCCAPS_MASKZ;
71 pc->dwRasterCaps = D3DPRASTERCAPS_DITHER | D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_FOGTABLE |
72 D3DPRASTERCAPS_FOGVERTEX | D3DPRASTERCAPS_STIPPLE | D3DPRASTERCAPS_ZBIAS | D3DPRASTERCAPS_ZTEST;
73 pc->dwZCmpCaps = 0xFFFFFFFF; /* All Z test can be done */
74 pc->dwSrcBlendCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
75 pc->dwDestBlendCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
76 pc->dwAlphaCmpCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
77 pc->dwShadeCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
78 pc->dwTextureCaps = D3DPTEXTURECAPS_ALPHA | D3DPTEXTURECAPS_BORDER | D3DPTEXTURECAPS_PERSPECTIVE |
79 D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_TRANSPARENCY;
80 pc->dwTextureFilterCaps = D3DPTFILTERCAPS_LINEAR | D3DPTFILTERCAPS_LINEARMIPLINEAR | D3DPTFILTERCAPS_LINEARMIPNEAREST |
81 D3DPTFILTERCAPS_MIPLINEAR | D3DPTFILTERCAPS_MIPNEAREST | D3DPTFILTERCAPS_NEAREST;
82 pc->dwTextureBlendCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
83 pc->dwTextureAddressCaps = D3DPTADDRESSCAPS_BORDER | D3DPTADDRESSCAPS_CLAMP | D3DPTADDRESSCAPS_WRAP;
84 pc->dwStippleWidth = 32;
85 pc->dwStippleHeight = 32;
88 static void fill_opengl_caps(D3DDEVICEDESC *d1, D3DDEVICEDESC *d2)
92 d1->dwSize = sizeof(*d1);
93 d1->dwFlags = D3DDD_DEVCAPS | D3DDD_BCLIPPING | D3DDD_COLORMODEL | D3DDD_DEVICERENDERBITDEPTH | D3DDD_DEVICEZBUFFERBITDEPTH
94 | D3DDD_LIGHTINGCAPS | D3DDD_LINECAPS | D3DDD_MAXBUFFERSIZE | D3DDD_MAXVERTEXCOUNT | D3DDD_TRANSFORMCAPS | D3DDD_TRICAPS;
95 d1->dcmColorModel = D3DCOLOR_RGB;
96 d1->dwDevCaps = D3DDEVCAPS_CANRENDERAFTERFLIP | D3DDEVCAPS_DRAWPRIMTLVERTEX | D3DDEVCAPS_EXECUTESYSTEMMEMORY |
97 D3DDEVCAPS_EXECUTEVIDEOMEMORY | D3DDEVCAPS_FLOATTLVERTEX | D3DDEVCAPS_TEXTURENONLOCALVIDMEM | D3DDEVCAPS_TEXTURESYSTEMMEMORY |
98 D3DDEVCAPS_TEXTUREVIDEOMEMORY | D3DDEVCAPS_TLVERTEXSYSTEMMEMORY | D3DDEVCAPS_TLVERTEXVIDEOMEMORY;
99 d1->dtcTransformCaps.dwSize = sizeof(D3DTRANSFORMCAPS);
100 d1->dtcTransformCaps.dwCaps = D3DTRANSFORMCAPS_CLIP;
101 d1->bClipping = TRUE;
102 d1->dlcLightingCaps.dwSize = sizeof(D3DLIGHTINGCAPS);
103 d1->dlcLightingCaps.dwCaps = D3DLIGHTCAPS_DIRECTIONAL | D3DLIGHTCAPS_PARALLELPOINT | D3DLIGHTCAPS_POINT | D3DLIGHTCAPS_SPOT;
104 d1->dlcLightingCaps.dwLightingModel = D3DLIGHTINGMODEL_RGB;
105 d1->dlcLightingCaps.dwNumLights = 16; /* glGetIntegerv(GL_MAX_LIGHTS, &maxlight); d1->dlcLightingCaps.dwNumLights = maxlight; */
106 fill_opengl_primcaps(&(d1->dpcLineCaps));
107 fill_opengl_primcaps(&(d1->dpcTriCaps));
108 d1->dwDeviceRenderBitDepth = DDBD_16;
109 d1->dwDeviceZBufferBitDepth = DDBD_16;
110 d1->dwMaxBufferSize = 0;
111 d1->dwMaxVertexCount = 65536;
112 d1->dwMinTextureWidth = 1;
113 d1->dwMinTextureHeight = 1;
114 d1->dwMaxTextureWidth = 256; /* This is for Mesa on top of Glide (in the future :-) ) */
115 d1->dwMaxTextureHeight = 256; /* This is for Mesa on top of Glide (in the future :-) ) */
116 d1->dwMinStippleWidth = 1;
117 d1->dwMinStippleHeight = 1;
118 d1->dwMaxStippleWidth = 32;
119 d1->dwMaxStippleHeight = 32;
121 d2->dwSize = sizeof(*d2);
125 int d3d_OpenGL(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) {
128 TRACE(ddraw," Enumerating OpenGL D3D device.\n");
130 fill_opengl_caps(&d1, &d2);
132 return cb((void*)&IID_D3DDEVICE2_OpenGL,"WINE Direct3D using OpenGL","direct3d",&d1,&d2,context);
135 int is_OpenGL(REFCLSID rguid, LPDIRECTDRAWSURFACE surface, LPDIRECT3DDEVICE2 *device, LPDIRECT3D2 d3d)
137 if (/* Default device */
140 (!memcmp(&IID_IDirect3DHALDevice,rguid,sizeof(IID_IDirect3DHALDevice))) ||
142 (!memcmp(&IID_D3DDEVICE2_OpenGL,rguid,sizeof(IID_D3DDEVICE2_OpenGL)))) {
143 OpenGL_IDirect3DDevice2 *odev;
145 const float id_mat[16] = {
152 *device = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(OpenGL_IDirect3DDevice2));
153 odev = (OpenGL_IDirect3DDevice2 *) (*device);
155 (*device)->lpvtbl = &OpenGL_vtable;
156 (*device)->d3d = d3d;
157 (*device)->surface = surface;
159 (*device)->viewport_list = NULL;
160 (*device)->current_viewport = NULL;
162 (*device)->set_context = set_context;
164 TRACE(ddraw, "OpenGL device created \n");
166 /* Create the OpenGL context */
167 odev->ctx = OSMesaCreateContext(OSMESA_RGBA, NULL);
168 odev->buffer = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
169 surface->s.surface_desc.dwWidth * surface->s.surface_desc.dwHeight * 4);
170 odev->rs.src = GL_ONE;
171 odev->rs.dst = GL_ZERO;
172 odev->rs.mag = GL_NEAREST;
173 odev->rs.min = GL_NEAREST;
176 memcpy(odev->world_mat, id_mat, 16 * sizeof(float));
177 memcpy(odev->view_mat , id_mat, 16 * sizeof(float));
178 memcpy(odev->proj_mat , id_mat, 16 * sizeof(float));
181 (*device)->set_context(*device);
182 glClearColor(0.0, 0.0, 0.0, 0.0);
183 glColor3f(1.0, 1.0, 1.0);
188 /* This is not the OpenGL UID */
192 /*******************************************************************************
193 * Common IDirect3DDevice2
196 static HRESULT WINAPI IDirect3DDevice2_QueryInterface(LPDIRECT3DDEVICE2 this,
202 WINE_StringFromCLSID((LPCLSID)riid,xrefiid);
203 FIXME(ddraw, "(%p)->(%s,%p): stub\n", this, xrefiid,ppvObj);
210 static ULONG WINAPI IDirect3DDevice2_AddRef(LPDIRECT3DDEVICE2 this)
212 TRACE(ddraw, "(%p)->()incrementing from %lu.\n", this, this->ref );
214 return ++(this->ref);
219 static ULONG WINAPI IDirect3DDevice2_Release(LPDIRECT3DDEVICE2 this)
221 FIXME( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
223 if (!--(this->ref)) {
224 HeapFree(GetProcessHeap(),0,this);
232 /*** IDirect3DDevice2 methods ***/
233 static HRESULT WINAPI IDirect3DDevice2_GetCaps(LPDIRECT3DDEVICE2 this,
234 LPD3DDEVICEDESC lpdescsoft,
235 LPD3DDEVICEDESC lpdeschard)
237 FIXME(ddraw, "(%p)->(%p,%p): stub\n", this, lpdescsoft, lpdeschard);
239 fill_opengl_caps(lpdescsoft, lpdeschard);
246 static HRESULT WINAPI IDirect3DDevice2_SwapTextureHandles(LPDIRECT3DDEVICE2 this,
247 LPDIRECT3DTEXTURE2 lptex1,
248 LPDIRECT3DTEXTURE2 lptex2)
250 FIXME(ddraw, "(%p)->(%p,%p): stub\n", this, lptex1, lptex2);
257 static HRESULT WINAPI IDirect3DDevice2_GetStats(LPDIRECT3DDEVICE2 this,
260 FIXME(ddraw, "(%p)->(%p): stub\n", this, lpstats);
267 static HRESULT WINAPI IDirect3DDevice2_AddViewport(LPDIRECT3DDEVICE2 this,
268 LPDIRECT3DVIEWPORT2 lpvp)
270 FIXME(ddraw, "(%p)->(%p): stub\n", this, lpvp);
272 /* Adds this viewport to the viewport list */
273 lpvp->next = this->viewport_list;
274 this->viewport_list = lpvp;
281 static HRESULT WINAPI IDirect3DDevice2_DeleteViewport(LPDIRECT3DDEVICE2 this,
282 LPDIRECT3DVIEWPORT2 lpvp)
284 LPDIRECT3DVIEWPORT2 cur, prev;
285 FIXME(ddraw, "(%p)->(%p): stub\n", this, lpvp);
287 /* Finds this viewport in the list */
289 cur = this->viewport_list;
290 while ((cur != NULL) && (cur != lpvp)) {
295 return DDERR_INVALIDOBJECT;
299 this->viewport_list = cur->next;
301 prev->next = cur->next;
308 static HRESULT WINAPI IDirect3DDevice2_NextViewport(LPDIRECT3DDEVICE2 this,
309 LPDIRECT3DVIEWPORT2 lpvp,
310 LPDIRECT3DVIEWPORT2* lplpvp,
313 FIXME(ddraw, "(%p)->(%p,%p,%08lx): stub\n", this, lpvp, lpvp, dwFlags);
317 *lplpvp = lpvp->next;
321 *lplpvp = this->viewport_list;
325 lpvp = this->viewport_list;
326 while (lpvp->next != NULL)
333 return DDERR_INVALIDPARAMS;
339 static HRESULT enum_texture_format_OpenGL(LPD3DENUMTEXTUREFORMATSCALLBACK cb,
342 LPDDPIXELFORMAT pformat;
344 /* Do the texture enumeration */
345 sdesc.dwSize = sizeof(DDSURFACEDESC);
346 sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
347 sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
348 pformat = &(sdesc.ddpfPixelFormat);
349 pformat->dwSize = sizeof(DDPIXELFORMAT);
350 pformat->dwFourCC = 0;
352 TRACE(ddraw, "Enumerating GL_RGBA unpacked (32)\n");
353 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
354 pformat->x.dwRGBBitCount = 32;
355 pformat->y.dwRBitMask = 0xFF000000;
356 pformat->z.dwGBitMask = 0x00FF0000;
357 pformat->xx.dwBBitMask = 0x0000FF00;
358 pformat->xy.dwRGBAlphaBitMask = 0x000000FF;
359 if (cb(&sdesc, context) == 0)
362 TRACE(ddraw, "Enumerating GL_RGB unpacked (24)\n");
363 pformat->dwFlags = DDPF_RGB;
364 pformat->x.dwRGBBitCount = 24;
365 pformat->y.dwRBitMask = 0x00FF0000;
366 pformat->z.dwGBitMask = 0x0000FF00;
367 pformat->xx.dwBBitMask = 0x000000FF;
368 pformat->xy.dwRGBAlphaBitMask = 0x00000000;
369 if (cb(&sdesc, context) == 0)
372 #ifndef HAVE_BUGGY_MESAGL
373 /* The packed texture format are buggy in Mesa. The bug was reported and corrected,
374 so that future version will work great. */
375 TRACE(ddraw, "Enumerating GL_RGB packed GL_UNSIGNED_SHORT_5_6_5 (16)\n");
376 pformat->dwFlags = DDPF_RGB;
377 pformat->x.dwRGBBitCount = 16;
378 pformat->y.dwRBitMask = 0x0000F800;
379 pformat->z.dwGBitMask = 0x000007E0;
380 pformat->xx.dwBBitMask = 0x0000001F;
381 pformat->xy.dwRGBAlphaBitMask = 0x00000000;
382 if (cb(&sdesc, context) == 0)
385 TRACE(ddraw, "Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_5_5_5_1 (16)\n");
386 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
387 pformat->x.dwRGBBitCount = 16;
388 pformat->y.dwRBitMask = 0x0000F800;
389 pformat->z.dwGBitMask = 0x000007C0;
390 pformat->xx.dwBBitMask = 0x0000003E;
391 pformat->xy.dwRGBAlphaBitMask = 0x00000001;
392 if (cb(&sdesc, context) == 0)
395 TRACE(ddraw, "Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_4_4_4_4 (16)\n");
396 pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
397 pformat->x.dwRGBBitCount = 16;
398 pformat->y.dwRBitMask = 0x0000F000;
399 pformat->z.dwGBitMask = 0x00000F00;
400 pformat->xx.dwBBitMask = 0x000000F0;
401 pformat->xy.dwRGBAlphaBitMask = 0x0000000F;
402 if (cb(&sdesc, context) == 0)
405 TRACE(ddraw, "Enumerating GL_RGB packed GL_UNSIGNED_BYTE_3_3_2 (8)\n");
406 pformat->dwFlags = DDPF_RGB;
407 pformat->x.dwRGBBitCount = 8;
408 pformat->y.dwRBitMask = 0x0000F800;
409 pformat->z.dwGBitMask = 0x000007C0;
410 pformat->xx.dwBBitMask = 0x0000003E;
411 pformat->xy.dwRGBAlphaBitMask = 0x00000001;
412 if (cb(&sdesc, context) == 0)
416 TRACE(ddraw, "Enumerating Paletted (8)\n");
417 pformat->dwFlags = DDPF_PALETTEINDEXED8;
418 pformat->x.dwRGBBitCount = 8;
419 pformat->y.dwRBitMask = 0x00000000;
420 pformat->z.dwGBitMask = 0x00000000;
421 pformat->xx.dwBBitMask = 0x00000000;
422 pformat->xy.dwRGBAlphaBitMask = 0x00000000;
423 if (cb(&sdesc, context) == 0)
426 TRACE(ddraw, "End of enumeration\n");
431 static HRESULT WINAPI IDirect3DDevice2_EnumTextureFormats(LPDIRECT3DDEVICE2 this,
432 LPD3DENUMTEXTUREFORMATSCALLBACK cb,
435 FIXME(ddraw, "(%p)->(%p,%p): stub\n", this, cb, context);
437 return enum_texture_format_OpenGL(cb, context);
442 static HRESULT WINAPI IDirect3DDevice2_BeginScene(LPDIRECT3DDEVICE2 this)
444 /* OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) this; */
446 FIXME(ddraw, "(%p)->(): stub\n", this);
448 /* Here, we should get the DDraw surface and 'copy it' to the
449 OpenGL surface.... */
456 static HRESULT WINAPI IDirect3DDevice2_EndScene(LPDIRECT3DDEVICE2 this)
458 OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) this;
459 LPDIRECTDRAWSURFACE3 surf = (LPDIRECTDRAWSURFACE3) this->surface;
463 unsigned short *dest;
465 FIXME(ddraw, "(%p)->(): stub\n", this);
467 /* Here we copy back the OpenGL scene to the the DDraw surface */
468 /* First, lock the surface */
469 surf->lpvtbl->fnLock(surf,NULL,&sdesc,DDLOCK_WRITEONLY,0);
471 /* The copy the OpenGL buffer to this surface */
473 /* NOTE : this is only for debugging purpose. I KNOW it is really unoptimal.
474 I am currently working on a set of patches for Mesa to have OSMesa support
475 16 bpp surfaces => we will able to render directly onto the surface, no
476 need to do a bpp conversion */
477 dest = (unsigned short *) sdesc.y.lpSurface;
478 src = ((unsigned char *) odev->buffer) + 4 * (sdesc.dwWidth * (sdesc.dwHeight - 1));
479 for (y = 0; y < sdesc.dwHeight; y++) {
480 unsigned char *lsrc = src;
482 for (x = 0; x < sdesc.dwWidth ; x++) {
483 unsigned char r = *lsrc++;
484 unsigned char g = *lsrc++;
485 unsigned char b = *lsrc++;
487 *dest = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
492 src -= 4 * sdesc.dwWidth;
495 /* Unlock the surface */
496 surf->lpvtbl->fnUnlock(surf,sdesc.y.lpSurface);
503 static HRESULT WINAPI IDirect3DDevice2_GetDirect3D(LPDIRECT3DDEVICE2 this, LPDIRECT3D2 *lpd3d2)
505 TRACE(ddraw, "(%p)->(%p): stub\n", this, lpd3d2);
514 /*** DrawPrimitive API ***/
515 static HRESULT WINAPI IDirect3DDevice2_SetCurrentViewport(LPDIRECT3DDEVICE2 this,
516 LPDIRECT3DVIEWPORT2 lpvp)
518 FIXME(ddraw, "(%p)->(%p): stub\n", this, lpvp);
520 /* Should check if the viewport was added or not */
522 /* Set this viewport as the current viewport */
523 this->current_viewport = lpvp;
525 /* Activate this viewport */
526 lpvp->device.active_device2 = this;
527 lpvp->activate(lpvp);
534 static HRESULT WINAPI IDirect3DDevice2_GetCurrentViewport(LPDIRECT3DDEVICE2 this,
535 LPDIRECT3DVIEWPORT2 *lplpvp)
537 FIXME(ddraw, "(%p)->(%p): stub\n", this, lplpvp);
539 /* Returns the current viewport */
540 *lplpvp = this->current_viewport;
547 static HRESULT WINAPI IDirect3DDevice2_SetRenderTarget(LPDIRECT3DDEVICE2 this,
548 LPDIRECTDRAWSURFACE lpdds,
551 FIXME(ddraw, "(%p)->(%p,%08lx): stub\n", this, lpdds, dwFlags);
558 static HRESULT WINAPI IDirect3DDevice2_GetRenderTarget(LPDIRECT3DDEVICE2 this,
559 LPDIRECTDRAWSURFACE *lplpdds)
561 FIXME(ddraw, "(%p)->(%p): stub\n", this, lplpdds);
563 /* Returns the current rendering target (the surface on wich we render) */
564 *lplpdds = this->surface;
571 static HRESULT WINAPI IDirect3DDevice2_Begin(LPDIRECT3DDEVICE2 this,
572 D3DPRIMITIVETYPE d3dp,
576 FIXME(ddraw, "(%p)->(%d,%d,%08lx): stub\n", this, d3dp, d3dv, dwFlags);
583 static HRESULT WINAPI IDirect3DDevice2_BeginIndexed(LPDIRECT3DDEVICE2 this,
584 D3DPRIMITIVETYPE d3dp,
590 FIXME(ddraw, "(%p)->(%d,%d,%p,%ld,%08lx): stub\n", this, d3dp, d3dv, lpvert, numvert, dwFlags);
597 static HRESULT WINAPI IDirect3DDevice2_Vertex(LPDIRECT3DDEVICE2 this,
600 FIXME(ddraw, "(%p)->(%p): stub\n", this, lpvert);
607 static HRESULT WINAPI IDirect3DDevice2_Index(LPDIRECT3DDEVICE2 this,
610 FIXME(ddraw, "(%p)->(%d): stub\n", this, index);
617 static HRESULT WINAPI IDirect3DDevice2_End(LPDIRECT3DDEVICE2 this,
620 FIXME(ddraw, "(%p)->(%08lx): stub\n", this, dwFlags);
628 static HRESULT WINAPI IDirect3DDevice2_GetRenderState(LPDIRECT3DDEVICE2 this,
629 D3DRENDERSTATETYPE d3drs,
632 FIXME(ddraw, "(%p)->(%d,%p): stub\n", this, d3drs, lprstate);
639 static HRESULT WINAPI IDirect3DDevice2_SetRenderState(LPDIRECT3DDEVICE2 this,
640 D3DRENDERSTATETYPE dwRenderStateType,
643 OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) this;
645 TRACE(ddraw, "(%p)->(%d,%ld)\n", this, dwRenderStateType, dwRenderState);
647 /* Call the render state functions */
648 set_render_state(dwRenderStateType, dwRenderState, &(odev->rs));
655 static HRESULT WINAPI IDirect3DDevice2_GetLightState(LPDIRECT3DDEVICE2 this,
656 D3DLIGHTSTATETYPE d3dls,
659 FIXME(ddraw, "(%p)->(%d,%p): stub\n", this, d3dls, lplstate);
666 static HRESULT WINAPI IDirect3DDevice2_SetLightState(LPDIRECT3DDEVICE2 this,
667 D3DLIGHTSTATETYPE dwLightStateType,
670 FIXME(ddraw, "(%p)->(%d,%08lx): stub\n", this, dwLightStateType, dwLightState);
672 switch (dwLightStateType) {
673 case D3DLIGHTSTATE_MATERIAL: { /* 1 */
674 LPDIRECT3DMATERIAL2 mat = (LPDIRECT3DMATERIAL2) dwLightState;
679 TRACE(ddraw, "Zoups !!!\n");
683 case D3DLIGHTSTATE_AMBIENT: { /* 2 */
686 light[0] = ((dwLightState >> 16) & 0xFF) / 255.0;
687 light[1] = ((dwLightState >> 8) & 0xFF) / 255.0;
688 light[2] = ((dwLightState >> 0) & 0xFF) / 255.0;
690 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (float *) light);
693 case D3DLIGHTSTATE_COLORMODEL: /* 3 */
696 case D3DLIGHTSTATE_FOGMODE: /* 4 */
699 case D3DLIGHTSTATE_FOGSTART: /* 5 */
702 case D3DLIGHTSTATE_FOGEND: /* 6 */
705 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */
709 TRACE(ddraw, "Unexpected Light State Type\n");
710 return DDERR_INVALIDPARAMS;
718 static HRESULT WINAPI IDirect3DDevice2_SetTransform(LPDIRECT3DDEVICE2 this,
719 D3DTRANSFORMSTATETYPE d3dts,
720 LPD3DMATRIX lpmatrix)
722 OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) this;
724 FIXME(ddraw, "(%p)->(%d,%p): stub\n", this, d3dts, lpmatrix);
726 /* Using a trial and failure approach, I found that the order of
727 Direct3D transformations that works best is :
729 ScreenCoord = ProjectionMat * ViewMat * WorldMat * ObjectCoord
731 As OpenGL uses only two matrices, I combined PROJECTION and VIEW into
732 OpenGL's GL_PROJECTION matrix and the WORLD into GL_MODELVIEW.
734 If anyone has a good explanation of the three different matrices in
735 the SDK online documentation, feel free to point it to me. For example,
736 which matrices transform lights ? In OpenGL only the PROJECTION matrix
737 transform the lights, not the MODELVIEW. Using the matrix names, I
738 supposed that PROJECTION and VIEW (all 'camera' related names) do
739 transform lights, but WORLD do not. It may be wrong though... */
741 /* After reading through both OpenGL and Direct3D documentations, I
742 thought that D3D matrices were written in 'line major mode' transposed
743 from OpenGL's 'column major mode'. But I found out that a simple memcpy
744 works fine to transfer one matrix format to the other (it did not work
745 when transposing)....
748 1) are the documentations wrong
749 2) does the matrix work even if they are not read correctly
750 3) is Mesa's implementation of OpenGL not compliant regarding Matrix
751 loading using glLoadMatrix ?
753 Anyway, I always use 'conv_mat' to transfer the matrices from one format
754 to the other so that if I ever find out that I need to transpose them, I
755 will able to do it quickly, only by changing the macro conv_mat. */
758 case D3DTRANSFORMSTATE_WORLD: {
759 conv_mat(lpmatrix, odev->world_mat);
760 glMatrixMode(GL_MODELVIEW);
761 glLoadMatrixf((float *) &(odev->world_mat));
764 case D3DTRANSFORMSTATE_VIEW: {
765 conv_mat(lpmatrix, odev->view_mat);
766 glMatrixMode(GL_PROJECTION);
767 glLoadMatrixf((float *) &(odev->proj_mat));
768 glMultMatrixf((float *) &(odev->view_mat));
771 case D3DTRANSFORMSTATE_PROJECTION: {
772 conv_mat(lpmatrix, odev->proj_mat);
773 glMatrixMode(GL_PROJECTION);
774 glLoadMatrixf((float *) &(odev->proj_mat));
775 glMultMatrixf((float *) &(odev->view_mat));
787 static HRESULT WINAPI IDirect3DDevice2_GetTransform(LPDIRECT3DDEVICE2 this,
788 D3DTRANSFORMSTATETYPE d3dts,
789 LPD3DMATRIX lpmatrix)
791 FIXME(ddraw, "(%p)->(%d,%p): stub\n", this, d3dts, lpmatrix);
798 static HRESULT WINAPI IDirect3DDevice2_MultiplyTransform(LPDIRECT3DDEVICE2 this,
799 D3DTRANSFORMSTATETYPE d3dts,
800 LPD3DMATRIX lpmatrix)
802 FIXME(ddraw, "(%p)->(%d,%p): stub\n", this, d3dts, lpmatrix);
807 #define DRAW_PRIMITIVE(MAXVERT,INDEX) \
808 /* Puts GL in the correct lighting mode */ \
809 if (odev->vt != d3dv) { \
810 if (odev->vt == D3DVT_TLVERTEX) { \
811 /* Need to put the correct transformation again */ \
812 glMatrixMode(GL_MODELVIEW); \
813 glLoadMatrixf((float *) &(odev->world_mat)); \
814 glMatrixMode(GL_PROJECTION); \
815 glLoadMatrixf((float *) &(odev->proj_mat)); \
816 glMultMatrixf((float *) &(odev->view_mat)); \
821 TRACE(ddraw, "Standard Vertex\n"); \
822 glEnable(GL_LIGHTING); \
825 case D3DVT_LVERTEX: \
826 TRACE(ddraw, "Lighted Vertex\n"); \
827 glDisable(GL_LIGHTING); \
830 case D3DVT_TLVERTEX: { \
831 GLdouble height, width, minZ, maxZ; \
833 TRACE(ddraw, "Transformed - Lighted Vertex\n"); \
834 /* First, disable lighting */ \
835 glDisable(GL_LIGHTING); \
837 /* Then do not put any transformation matrixes */ \
838 glMatrixMode(GL_MODELVIEW); \
840 glMatrixMode(GL_PROJECTION); \
843 if (this->current_viewport == NULL) { \
844 ERR(ddraw, "No current viewport !\n"); \
845 /* Using standard values */ \
851 if (this->current_viewport->use_vp2) { \
852 height = (GLdouble) this->current_viewport->viewport.vp2.dwHeight; \
853 width = (GLdouble) this->current_viewport->viewport.vp2.dwWidth; \
854 minZ = (GLdouble) this->current_viewport->viewport.vp2.dvMinZ; \
855 maxZ = (GLdouble) this->current_viewport->viewport.vp2.dvMaxZ; \
857 height = (GLdouble) this->current_viewport->viewport.vp1.dwHeight; \
858 width = (GLdouble) this->current_viewport->viewport.vp1.dwWidth; \
859 minZ = (GLdouble) this->current_viewport->viewport.vp1.dvMinZ; \
860 maxZ = (GLdouble) this->current_viewport->viewport.vp1.dvMaxZ; \
864 glOrtho(0.0, width, height, 0.0, -minZ, -maxZ); \
868 ERR(ddraw, "Unhandled vertex type\n"); \
876 case D3DPT_POINTLIST: \
877 TRACE(ddraw, "Start POINTS\n"); \
878 glBegin(GL_POINTS); \
881 case D3DPT_LINELIST: \
882 TRACE(ddraw, "Start LINES\n"); \
886 case D3DPT_LINESTRIP: \
887 TRACE(ddraw, "Start LINE_STRIP\n"); \
888 glBegin(GL_LINE_STRIP); \
891 case D3DPT_TRIANGLELIST: \
892 TRACE(ddraw, "Start TRIANGLES\n"); \
893 glBegin(GL_TRIANGLES); \
896 case D3DPT_TRIANGLESTRIP: \
897 TRACE(ddraw, "Start TRIANGLE_STRIP\n"); \
898 glBegin(GL_TRIANGLE_STRIP); \
901 case D3DPT_TRIANGLEFAN: \
902 TRACE(ddraw, "Start TRIANGLE_FAN\n"); \
903 glBegin(GL_TRIANGLE_FAN); \
907 TRACE(ddraw, "Unhandled primitive\n"); \
911 /* Draw the primitives */ \
912 for (vx_index = 0; vx_index < MAXVERT; vx_index++) { \
914 case D3DVT_VERTEX: { \
915 D3DVERTEX *vx = ((D3DVERTEX *) lpvertex) + INDEX; \
917 glNormal3f(vx->nx.nx, vx->ny.ny, vx->nz.nz); \
918 glVertex3f(vx->x.x, vx->y.y, vx->z.z); \
919 TRACE(ddraw, " V: %f %f %f\n", vx->x.x, vx->y.y, vx->z.z); \
922 case D3DVT_LVERTEX: { \
923 D3DLVERTEX *vx = ((D3DLVERTEX *) lpvertex) + INDEX; \
924 DWORD col = vx->c.color; \
926 glColor3f(((col >> 16) & 0xFF) / 255.0, \
927 ((col >> 8) & 0xFF) / 255.0, \
928 ((col >> 0) & 0xFF) / 255.0); \
929 glVertex3f(vx->x.x, vx->y.y, vx->z.z); \
930 TRACE(ddraw, " LV: %f %f %f (%02lx %02lx %02lx)\n", \
931 vx->x.x, vx->y.y, vx->z.z, \
932 ((col >> 16) & 0xFF), ((col >> 8) & 0xFF), ((col >> 0) & 0xFF)); \
935 case D3DVT_TLVERTEX: { \
936 D3DTLVERTEX *vx = ((D3DTLVERTEX *) lpvertex) + INDEX; \
937 DWORD col = vx->c.color; \
939 glColor3f(((col >> 16) & 0xFF) / 255.0, \
940 ((col >> 8) & 0xFF) / 255.0, \
941 ((col >> 0) & 0xFF) / 255.0); \
942 glTexCoord2f(vx->u.tu, vx->v.tv); \
943 if (vx->r.rhw < 0.01) \
944 glVertex3f(vx->x.sx, \
948 glVertex4f(vx->x.sx / vx->r.rhw, \
949 vx->y.sy / vx->r.rhw, \
950 vx->z.sz / vx->r.rhw, \
952 TRACE(ddraw, " TLV: %f %f %f (%02lx %02lx %02lx) (%f %f) (%f)\n", \
953 vx->x.sx, vx->y.sy, vx->z.sz, \
954 ((col >> 16) & 0xFF), ((col >> 8) & 0xFF), ((col >> 0) & 0xFF), \
955 vx->u.tu, vx->v.tv, vx->r.rhw); \
959 TRACE(ddraw, "Unhandled vertex type\n"); \
965 TRACE(ddraw, "End\n");
968 static HRESULT WINAPI IDirect3DDevice2_DrawPrimitive(LPDIRECT3DDEVICE2 this,
969 D3DPRIMITIVETYPE d3dp,
975 OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) this;
978 TRACE(ddraw, "(%p)->(%d,%d,%p,%ld,%08lx): stub\n", this, d3dp, d3dv, lpvertex, vertcount, dwFlags);
980 DRAW_PRIMITIVE(vertcount, vx_index);
987 static HRESULT WINAPI IDirect3DDevice2_DrawIndexedPrimitive(LPDIRECT3DDEVICE2 this,
988 D3DPRIMITIVETYPE d3dp,
996 OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) this;
999 TRACE(ddraw, "(%p)->(%d,%d,%p,%ld,%p,%ld,%08lx): stub\n", this, d3dp, d3dv, lpvertex, vertcount, lpindexes, indexcount, dwFlags);
1001 DRAW_PRIMITIVE(indexcount, lpindexes[vx_index]);
1008 static HRESULT WINAPI IDirect3DDevice2_SetClipStatus(LPDIRECT3DDEVICE2 this,
1009 LPD3DCLIPSTATUS lpcs)
1011 FIXME(ddraw, "(%p)->(%p): stub\n", this, lpcs);
1018 static HRESULT WINAPI IDirect3DDevice2_GetClipStatus(LPDIRECT3DDEVICE2 this,
1019 LPD3DCLIPSTATUS lpcs)
1021 FIXME(ddraw, "(%p)->(%p): stub\n", this, lpcs);
1028 /*******************************************************************************
1029 * OpenGL-specific IDirect3DDevice2
1032 /*******************************************************************************
1033 * OpenGL-specific VTable
1036 static IDirect3DDevice2_VTable OpenGL_vtable = {
1037 IDirect3DDevice2_QueryInterface,
1038 IDirect3DDevice2_AddRef,
1039 IDirect3DDevice2_Release,
1040 /*** IDirect3DDevice2 methods ***/
1041 IDirect3DDevice2_GetCaps,
1042 IDirect3DDevice2_SwapTextureHandles,
1043 IDirect3DDevice2_GetStats,
1044 IDirect3DDevice2_AddViewport,
1045 IDirect3DDevice2_DeleteViewport,
1046 IDirect3DDevice2_NextViewport,
1047 IDirect3DDevice2_EnumTextureFormats,
1048 IDirect3DDevice2_BeginScene,
1049 IDirect3DDevice2_EndScene,
1050 IDirect3DDevice2_GetDirect3D,
1052 /*** DrawPrimitive API ***/
1053 IDirect3DDevice2_SetCurrentViewport,
1054 IDirect3DDevice2_GetCurrentViewport,
1056 IDirect3DDevice2_SetRenderTarget,
1057 IDirect3DDevice2_GetRenderTarget,
1059 IDirect3DDevice2_Begin,
1060 IDirect3DDevice2_BeginIndexed,
1061 IDirect3DDevice2_Vertex,
1062 IDirect3DDevice2_Index,
1063 IDirect3DDevice2_End,
1065 IDirect3DDevice2_GetRenderState,
1066 IDirect3DDevice2_SetRenderState,
1067 IDirect3DDevice2_GetLightState,
1068 IDirect3DDevice2_SetLightState,
1069 IDirect3DDevice2_SetTransform,
1070 IDirect3DDevice2_GetTransform,
1071 IDirect3DDevice2_MultiplyTransform,
1073 IDirect3DDevice2_DrawPrimitive,
1074 IDirect3DDevice2_DrawIndexedPrimitive,
1076 IDirect3DDevice2_SetClipStatus,
1077 IDirect3DDevice2_GetClipStatus,
1080 /*******************************************************************************
1083 int d3d_OpenGL_dx3(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) {
1084 D3DDEVICEDESC d1,d2;
1086 TRACE(ddraw," Enumerating OpenGL D3D device.\n");
1088 fill_opengl_caps(&d1, &d2);
1090 return cb((void*)&IID_D3DDEVICE_OpenGL,"WINE Direct3D using OpenGL","direct3d",&d1,&d2,context);
1093 float id_mat[16] = {
1100 int is_OpenGL_dx3(REFCLSID rguid, LPDIRECTDRAWSURFACE surface, LPDIRECT3DDEVICE *device)
1102 if (!memcmp(&IID_D3DDEVICE_OpenGL,rguid,sizeof(IID_D3DDEVICE_OpenGL))) {
1103 OpenGL_IDirect3DDevice *odev;
1105 *device = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(OpenGL_IDirect3DDevice));
1106 odev = (OpenGL_IDirect3DDevice *) (*device);
1108 (*device)->lpvtbl = &OpenGL_vtable_dx3;
1109 (*device)->d3d = NULL;
1110 (*device)->surface = surface;
1112 (*device)->viewport_list = NULL;
1113 (*device)->current_viewport = NULL;
1115 (*device)->set_context = set_context_dx3;
1117 TRACE(ddraw, "OpenGL device created \n");
1119 /* Create the OpenGL context */
1120 odev->ctx = OSMesaCreateContext(OSMESA_RGBA, NULL);
1121 odev->buffer = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
1122 surface->s.surface_desc.dwWidth * surface->s.surface_desc.dwHeight * 4);
1123 odev->rs.src = GL_ONE;
1124 odev->rs.dst = GL_ZERO;
1125 odev->rs.mag = GL_NEAREST;
1126 odev->rs.min = GL_NEAREST;
1128 odev->world_mat = (LPD3DMATRIX) &id_mat;
1129 odev->view_mat = (LPD3DMATRIX) &id_mat;
1130 odev->proj_mat = (LPD3DMATRIX) &id_mat;
1132 /* Initialisation */
1133 (*device)->set_context(*device);
1134 glClearColor(0.0, 0.0, 0.0, 0.0);
1135 glColor3f(1.0, 1.0, 1.0);
1140 /* This is not the OpenGL UID */
1145 /*******************************************************************************
1148 static HRESULT WINAPI IDirect3DDevice_QueryInterface(LPDIRECT3DDEVICE this,
1154 WINE_StringFromCLSID((LPCLSID)riid,xrefiid);
1155 FIXME(ddraw, "(%p)->(%s,%p): stub\n", this, xrefiid,ppvObj);
1162 static ULONG WINAPI IDirect3DDevice_AddRef(LPDIRECT3DDEVICE this)
1164 TRACE(ddraw, "(%p)->()incrementing from %lu.\n", this, this->ref );
1166 return ++(this->ref);
1171 static ULONG WINAPI IDirect3DDevice_Release(LPDIRECT3DDEVICE this)
1173 FIXME( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1175 if (!--(this->ref)) {
1176 HeapFree(GetProcessHeap(),0,this);
1183 static HRESULT WINAPI IDirect3DDevice_Initialize(LPDIRECT3DDEVICE this,
1186 LPD3DDEVICEDESC lpd3ddvdesc)
1188 TRACE(ddraw, "(%p)->(%p,%p,%p): stub\n", this, lpd3d,lpGUID, lpd3ddvdesc);
1190 return DDERR_ALREADYINITIALIZED;
1194 static HRESULT WINAPI IDirect3DDevice_GetCaps(LPDIRECT3DDEVICE this,
1195 LPD3DDEVICEDESC lpD3DHWDevDesc,
1196 LPD3DDEVICEDESC lpD3DSWDevDesc)
1198 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpD3DHWDevDesc, lpD3DSWDevDesc);
1200 fill_opengl_caps(lpD3DHWDevDesc, lpD3DSWDevDesc);
1206 static HRESULT WINAPI IDirect3DDevice_SwapTextureHandles(LPDIRECT3DDEVICE this,
1207 LPDIRECT3DTEXTURE lpD3DTex1,
1208 LPDIRECT3DTEXTURE lpD3DTex2)
1210 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpD3DTex1, lpD3DTex2);
1215 static HRESULT WINAPI IDirect3DDevice_CreateExecuteBuffer(LPDIRECT3DDEVICE this,
1216 LPD3DEXECUTEBUFFERDESC lpDesc,
1217 LPDIRECT3DEXECUTEBUFFER *lplpDirect3DExecuteBuffer,
1218 IUnknown *pUnkOuter)
1220 TRACE(ddraw, "(%p)->(%p,%p,%p)\n", this, lpDesc, lplpDirect3DExecuteBuffer, pUnkOuter);
1222 *lplpDirect3DExecuteBuffer = d3dexecutebuffer_create(this, lpDesc);
1228 static HRESULT WINAPI IDirect3DDevice_GetStats(LPDIRECT3DDEVICE this,
1229 LPD3DSTATS lpD3DStats)
1231 TRACE(ddraw, "(%p)->(%p): stub\n", this, lpD3DStats);
1237 static HRESULT WINAPI IDirect3DDevice_Execute(LPDIRECT3DDEVICE this,
1238 LPDIRECT3DEXECUTEBUFFER lpDirect3DExecuteBuffer,
1239 LPDIRECT3DVIEWPORT lpDirect3DViewport,
1242 TRACE(ddraw, "(%p)->(%p,%p,%08ld): stub\n", this, lpDirect3DExecuteBuffer, lpDirect3DViewport, dwFlags);
1244 /* Put this as the default context */
1247 lpDirect3DExecuteBuffer->execute(lpDirect3DExecuteBuffer, this, lpDirect3DViewport);
1252 static HRESULT WINAPI IDirect3DDevice_AddViewport(LPDIRECT3DDEVICE this,
1253 LPDIRECT3DVIEWPORT lpvp)
1255 FIXME(ddraw, "(%p)->(%p): stub\n", this, lpvp);
1257 /* Adds this viewport to the viewport list */
1258 lpvp->next = this->viewport_list;
1259 this->viewport_list = lpvp;
1266 static HRESULT WINAPI IDirect3DDevice_DeleteViewport(LPDIRECT3DDEVICE this,
1267 LPDIRECT3DVIEWPORT lpvp)
1269 LPDIRECT3DVIEWPORT cur, prev;
1270 FIXME(ddraw, "(%p)->(%p): stub\n", this, lpvp);
1272 /* Finds this viewport in the list */
1274 cur = this->viewport_list;
1275 while ((cur != NULL) && (cur != lpvp)) {
1280 return DDERR_INVALIDOBJECT;
1284 this->viewport_list = cur->next;
1286 prev->next = cur->next;
1293 static HRESULT WINAPI IDirect3DDevice_NextViewport(LPDIRECT3DDEVICE this,
1294 LPDIRECT3DVIEWPORT lpvp,
1295 LPDIRECT3DVIEWPORT* lplpvp,
1298 FIXME(ddraw, "(%p)->(%p,%p,%08lx): stub\n", this, lpvp, lpvp, dwFlags);
1302 *lplpvp = lpvp->next;
1306 *lplpvp = this->viewport_list;
1310 lpvp = this->viewport_list;
1311 while (lpvp->next != NULL)
1318 return DDERR_INVALIDPARAMS;
1324 static HRESULT WINAPI IDirect3DDevice_Pick(LPDIRECT3DDEVICE this,
1325 LPDIRECT3DEXECUTEBUFFER lpDirect3DExecuteBuffer,
1326 LPDIRECT3DVIEWPORT lpDirect3DViewport,
1330 TRACE(ddraw, "(%p)->(%p,%p,%08lx,%p): stub\n", this, lpDirect3DExecuteBuffer, lpDirect3DViewport,
1337 static HRESULT WINAPI IDirect3DDevice_GetPickRecords(LPDIRECT3DDEVICE this,
1339 LPD3DPICKRECORD lpD3DPickRec)
1341 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpCount, lpD3DPickRec);
1347 static HRESULT WINAPI IDirect3DDevice_EnumTextureFormats(LPDIRECT3DDEVICE this,
1348 LPD3DENUMTEXTUREFORMATSCALLBACK lpd3dEnumTextureProc,
1351 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpd3dEnumTextureProc, lpArg);
1353 return enum_texture_format_OpenGL(lpd3dEnumTextureProc, lpArg);
1357 static HRESULT WINAPI IDirect3DDevice_CreateMatrix(LPDIRECT3DDEVICE this,
1358 LPD3DMATRIXHANDLE lpD3DMatHandle)
1360 TRACE(ddraw, "(%p)->(%p)\n", this, lpD3DMatHandle);
1362 *lpD3DMatHandle = (D3DMATRIXHANDLE) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(D3DMATRIX));
1368 static HRESULT WINAPI IDirect3DDevice_SetMatrix(LPDIRECT3DDEVICE this,
1369 D3DMATRIXHANDLE d3dMatHandle,
1370 const LPD3DMATRIX lpD3DMatrix)
1372 TRACE(ddraw, "(%p)->(%08lx,%p)\n", this, d3dMatHandle, lpD3DMatrix);
1374 dump_mat(lpD3DMatrix);
1376 *((D3DMATRIX *) d3dMatHandle) = *lpD3DMatrix;
1382 static HRESULT WINAPI IDirect3DDevice_GetMatrix(LPDIRECT3DDEVICE this,
1383 D3DMATRIXHANDLE D3DMatHandle,
1384 LPD3DMATRIX lpD3DMatrix)
1386 TRACE(ddraw, "(%p)->(%08lx,%p)\n", this, D3DMatHandle, lpD3DMatrix);
1388 *lpD3DMatrix = *((D3DMATRIX *) D3DMatHandle);
1394 static HRESULT WINAPI IDirect3DDevice_DeleteMatrix(LPDIRECT3DDEVICE this,
1395 D3DMATRIXHANDLE d3dMatHandle)
1397 TRACE(ddraw, "(%p)->(%08lx)\n", this, d3dMatHandle);
1399 HeapFree(GetProcessHeap(),0, (void *) d3dMatHandle);
1405 static HRESULT WINAPI IDirect3DDevice_BeginScene(LPDIRECT3DDEVICE this)
1407 /* OpenGL_IDirect3DDevice *odev = (OpenGL_IDirect3DDevice *) this; */
1409 FIXME(ddraw, "(%p)->(): stub\n", this);
1411 /* We get the pointer to the surface (should be done on flip) */
1412 /* odev->zb->pbuf = this->surface->s.surface_desc.y.lpSurface; */
1418 /* This is for the moment copy-pasted from IDirect3DDevice2...
1419 Will make a common function ... */
1420 static HRESULT WINAPI IDirect3DDevice_EndScene(LPDIRECT3DDEVICE this)
1422 OpenGL_IDirect3DDevice *odev = (OpenGL_IDirect3DDevice *) this;
1423 LPDIRECTDRAWSURFACE3 surf = (LPDIRECTDRAWSURFACE3) this->surface;
1424 DDSURFACEDESC sdesc;
1427 unsigned short *dest;
1429 FIXME(ddraw, "(%p)->(): stub\n", this);
1431 /* Here we copy back the OpenGL scene to the the DDraw surface */
1432 /* First, lock the surface */
1433 surf->lpvtbl->fnLock(surf,NULL,&sdesc,DDLOCK_WRITEONLY,0);
1435 /* The copy the OpenGL buffer to this surface */
1437 /* NOTE : this is only for debugging purpose. I KNOW it is really unoptimal.
1438 I am currently working on a set of patches for Mesa to have OSMesa support
1439 16 bpp surfaces => we will able to render directly onto the surface, no
1440 need to do a bpp conversion */
1441 dest = (unsigned short *) sdesc.y.lpSurface;
1442 src = ((unsigned char *) odev->buffer) + 4 * (sdesc.dwWidth * (sdesc.dwHeight - 1));
1443 for (y = 0; y < sdesc.dwHeight; y++) {
1444 unsigned char *lsrc = src;
1446 for (x = 0; x < sdesc.dwWidth ; x++) {
1447 unsigned char r = *lsrc++;
1448 unsigned char g = *lsrc++;
1449 unsigned char b = *lsrc++;
1452 *dest = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
1457 src -= 4 * sdesc.dwWidth;
1460 /* Unlock the surface */
1461 surf->lpvtbl->fnUnlock(surf,sdesc.y.lpSurface);
1467 static HRESULT WINAPI IDirect3DDevice_GetDirect3D(LPDIRECT3DDEVICE this,
1468 LPDIRECT3D *lpDirect3D)
1470 TRACE(ddraw, "(%p)->(%p): stub\n", this, lpDirect3D);
1477 /*******************************************************************************
1478 * Direct3DDevice VTable
1480 static IDirect3DDevice_VTable OpenGL_vtable_dx3 = {
1481 IDirect3DDevice_QueryInterface,
1482 IDirect3DDevice_AddRef,
1483 IDirect3DDevice_Release,
1484 IDirect3DDevice_Initialize,
1485 IDirect3DDevice_GetCaps,
1486 IDirect3DDevice_SwapTextureHandles,
1487 IDirect3DDevice_CreateExecuteBuffer,
1488 IDirect3DDevice_GetStats,
1489 IDirect3DDevice_Execute,
1490 IDirect3DDevice_AddViewport,
1491 IDirect3DDevice_DeleteViewport,
1492 IDirect3DDevice_NextViewport,
1493 IDirect3DDevice_Pick,
1494 IDirect3DDevice_GetPickRecords,
1495 IDirect3DDevice_EnumTextureFormats,
1496 IDirect3DDevice_CreateMatrix,
1497 IDirect3DDevice_SetMatrix,
1498 IDirect3DDevice_GetMatrix,
1499 IDirect3DDevice_DeleteMatrix,
1500 IDirect3DDevice_BeginScene,
1501 IDirect3DDevice_EndScene,
1502 IDirect3DDevice_GetDirect3D,
1505 #else /* HAVE_MESAGL */
1507 int d3d_OpenGL(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) {
1511 int is_OpenGL(REFCLSID rguid, LPDIRECTDRAWSURFACE surface, LPDIRECT3DDEVICE2 *device, LPDIRECT3D2 d3d)
1516 int d3d_OpenGL_dx3(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) {
1520 int is_OpenGL_dx3(REFCLSID rguid, LPDIRECTDRAWSURFACE surface, LPDIRECT3DDEVICE *device)
1525 #endif /* HAVE_MESAGL */