Keep track of per-column information inside the listview.
[wine] / dlls / ddraw / d3ddevice / mesa.c
1 /* Direct3D Device
2  * Copyright (c) 1998 Lionel ULMER
3  *
4  * This file contains the MESA implementation of all the D3D devices that
5  * Wine supports.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include "config.h"
23
24 #include <string.h>
25
26 #include "windef.h"
27 #include "winerror.h"
28 #include "wine/obj_base.h"
29 #include "ddraw.h"
30 #include "d3d.h"
31 #include "wine/debug.h"
32
33 #include "mesa_private.h"
34
35 #include "x11drv.h"
36
37 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
38
39 ICOM_VTABLE(IDirect3DDevice2) OpenGL_vtable;
40 ICOM_VTABLE(IDirect3DDevice) OpenGL_vtable_dx3;
41
42 /* Define this variable if you have an unpatched Mesa 3.0 (patches are available
43    on Mesa's home page) or version 3.1b.
44
45    Version 3.1b2 should correct this bug */
46 #undef HAVE_BUGGY_MESAGL
47
48 #define D3DDPRIVATE(x) mesa_d3dd_private *odev=((mesa_d3dd_private*)x->private)
49
50 #ifndef HAVE_GLEXT_PROTOTYPES
51 /* This is for non-OpenGL ABI compliant glext.h headers :-) */
52 typedef void (* PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat,
53                                          GLsizei width, GLenum format, GLenum type,
54                                          const GLvoid *table);
55 #endif
56
57 static const float id_mat[16] = {
58   1.0, 0.0, 0.0, 0.0,
59   0.0, 1.0, 0.0, 0.0,
60   0.0, 0.0, 1.0, 0.0,
61   0.0, 0.0, 0.0, 1.0
62 };
63
64 /* retrieve the X display to use on a given DC */
65 inline static Display *get_display( HDC hdc )
66 {
67     Display *display;
68     enum x11drv_escape_codes escape = X11DRV_GET_DISPLAY;
69
70     if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape,
71                     sizeof(display), (LPSTR)&display )) display = NULL;
72
73     return display;
74 }
75
76
77 /* retrieve the X drawable to use on a given DC */
78 inline static Drawable get_drawable( HDC hdc )
79 {
80     Drawable drawable;
81     enum x11drv_escape_codes escape = X11DRV_GET_DRAWABLE;
82
83     if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape,
84                     sizeof(drawable), (LPSTR)&drawable )) drawable = 0;
85
86     return drawable;
87 }
88
89
90 static BOOL opengl_flip( LPVOID display, LPVOID drawable)
91 {
92     TRACE("(%p, %ld)\n",(Display*)display,(Drawable)drawable);
93     ENTER_GL();
94     glXSwapBuffers((Display*)display,(Drawable)drawable);
95     LEAVE_GL();
96     return TRUE;
97 }
98
99
100 /*******************************************************************************
101  *                              OpenGL static functions
102  */
103 static void set_context(IDirect3DDevice2Impl* This) {
104 #if COMPILABLE
105     D3DDPRIVATE(This);
106
107     if (glXMakeCurrent(gdi_display,ddpriv->drawable, odev->ctx) == False) {
108         ERR("Error in setting current context (context %p drawable %ld)!\n",
109             odev->ctx, ddpriv->drawable);
110     }
111 #endif
112     D3DDPRIVATE(This);
113
114     ENTER_GL();
115     TRACE("glxMakeCurrent %p, %ld, %p\n",odev->gdi_display,odev->drawable, odev->ctx);
116     if (glXMakeCurrent(odev->gdi_display,odev->drawable, odev->ctx) == False) {
117         ERR("Error in setting current context (context %p drawable %ld)!\n",
118             odev->ctx, odev->drawable);
119     }
120     LEAVE_GL();
121 }
122
123 static void fill_opengl_primcaps(D3DPRIMCAPS *pc)
124 {
125   pc->dwSize = sizeof(*pc);
126   pc->dwMiscCaps = D3DPMISCCAPS_CONFORMANT | D3DPMISCCAPS_CULLCCW | D3DPMISCCAPS_CULLCW |
127     D3DPMISCCAPS_LINEPATTERNREP | D3DPMISCCAPS_MASKZ;
128   pc->dwRasterCaps = D3DPRASTERCAPS_DITHER | D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_FOGTABLE |
129     D3DPRASTERCAPS_FOGVERTEX | D3DPRASTERCAPS_STIPPLE | D3DPRASTERCAPS_ZBIAS | D3DPRASTERCAPS_ZTEST;
130   pc->dwZCmpCaps = 0xFFFFFFFF; /* All Z test can be done */
131   pc->dwSrcBlendCaps  = 0xFFFFFFFF; /* FIXME: need REAL values */
132   pc->dwDestBlendCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
133   pc->dwAlphaCmpCaps  = 0xFFFFFFFF; /* FIXME: need REAL values */
134   pc->dwShadeCaps = 0xFFFFFFFF;     /* FIXME: need REAL values */
135   pc->dwTextureCaps = D3DPTEXTURECAPS_ALPHA | D3DPTEXTURECAPS_BORDER | D3DPTEXTURECAPS_PERSPECTIVE |
136     D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_TRANSPARENCY;
137   pc->dwTextureFilterCaps = D3DPTFILTERCAPS_LINEAR | D3DPTFILTERCAPS_LINEARMIPLINEAR | D3DPTFILTERCAPS_LINEARMIPNEAREST |
138     D3DPTFILTERCAPS_MIPLINEAR | D3DPTFILTERCAPS_MIPNEAREST | D3DPTFILTERCAPS_NEAREST;
139   pc->dwTextureBlendCaps = 0xFFFFFFFF; /* FIXME: need REAL values */
140   pc->dwTextureAddressCaps = D3DPTADDRESSCAPS_BORDER | D3DPTADDRESSCAPS_CLAMP | D3DPTADDRESSCAPS_WRAP;
141   pc->dwStippleWidth = 32;
142   pc->dwStippleHeight = 32;
143 }
144
145 static void fill_opengl_caps(D3DDEVICEDESC *d1, D3DDEVICEDESC *d2)
146 {
147   /* GLint maxlight; */
148
149   d1->dwSize  = sizeof(*d1);
150   d1->dwFlags = D3DDD_DEVCAPS | D3DDD_BCLIPPING | D3DDD_COLORMODEL | D3DDD_DEVICERENDERBITDEPTH | D3DDD_DEVICEZBUFFERBITDEPTH
151     | D3DDD_LIGHTINGCAPS | D3DDD_LINECAPS | D3DDD_MAXBUFFERSIZE | D3DDD_MAXVERTEXCOUNT | D3DDD_TRANSFORMCAPS | D3DDD_TRICAPS;
152   d1->dcmColorModel = D3DCOLOR_RGB;
153   d1->dwDevCaps = D3DDEVCAPS_CANRENDERAFTERFLIP | D3DDEVCAPS_DRAWPRIMTLVERTEX | D3DDEVCAPS_EXECUTESYSTEMMEMORY |
154     D3DDEVCAPS_EXECUTEVIDEOMEMORY | D3DDEVCAPS_FLOATTLVERTEX | D3DDEVCAPS_TEXTURENONLOCALVIDMEM | D3DDEVCAPS_TEXTURESYSTEMMEMORY |
155       D3DDEVCAPS_TEXTUREVIDEOMEMORY | D3DDEVCAPS_TLVERTEXSYSTEMMEMORY | D3DDEVCAPS_TLVERTEXVIDEOMEMORY;
156   d1->dtcTransformCaps.dwSize = sizeof(D3DTRANSFORMCAPS);
157   d1->dtcTransformCaps.dwCaps = D3DTRANSFORMCAPS_CLIP;
158   d1->bClipping = TRUE;
159   d1->dlcLightingCaps.dwSize = sizeof(D3DLIGHTINGCAPS);
160   d1->dlcLightingCaps.dwCaps = D3DLIGHTCAPS_DIRECTIONAL | D3DLIGHTCAPS_PARALLELPOINT | D3DLIGHTCAPS_POINT | D3DLIGHTCAPS_SPOT;
161   d1->dlcLightingCaps.dwLightingModel = D3DLIGHTINGMODEL_RGB;
162   d1->dlcLightingCaps.dwNumLights = 16; /* glGetIntegerv(GL_MAX_LIGHTS, &maxlight); d1->dlcLightingCaps.dwNumLights = maxlight; */
163   fill_opengl_primcaps(&(d1->dpcLineCaps));
164   fill_opengl_primcaps(&(d1->dpcTriCaps));
165   d1->dwDeviceRenderBitDepth  = DDBD_16;
166   d1->dwDeviceZBufferBitDepth = DDBD_16;
167   d1->dwMaxBufferSize = 0;
168   d1->dwMaxVertexCount = 65536;
169   d1->dwMinTextureWidth  = 1;
170   d1->dwMinTextureHeight = 1;
171   d1->dwMaxTextureWidth  = 256; /* This is for Mesa on top of Glide (in the future :-) ) */
172   d1->dwMaxTextureHeight = 256; /* This is for Mesa on top of Glide (in the future :-) ) */
173   d1->dwMinStippleWidth  = 1;
174   d1->dwMinStippleHeight = 1;
175   d1->dwMaxStippleWidth  = 32;
176   d1->dwMaxStippleHeight = 32;
177
178   d2->dwSize  = sizeof(*d2);
179   d2->dwFlags = 0;
180 }
181
182 static void fill_device_capabilities(IDirectDrawImpl* ddraw) {
183 #if COMPILABLE
184   x11_dd_private *private = (x11_dd_private *) ddraw->d->private;
185   const char *ext_string;
186   Mesa_DeviceCapabilities *devcap;
187
188   private->device_capabilities = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(Mesa_DeviceCapabilities));
189   devcap = (Mesa_DeviceCapabilities *) private->device_capabilities;
190
191   ENTER_GL();
192   ext_string = glGetString(GL_EXTENSIONS);
193   /* Query for the ColorTable Extension */
194   if (strstr(ext_string, "GL_EXT_paletted_texture")) {
195     devcap->ptr_ColorTableEXT = (PFNGLCOLORTABLEEXTPROC) glXGetProcAddressARB("glColorTableEXT");
196     TRACE("Color table extension supported (function at %p)\n", devcap->ptr_ColorTableEXT);
197   } else {
198     TRACE("Color table extension not found.\n");
199   }
200   LEAVE_GL();
201 #endif
202 }
203
204 int d3d_OpenGL(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) {
205   D3DDEVICEDESC d1,d2;
206   TRACE(" Enumerating OpenGL D3D2 device (IID %s).\n", debugstr_guid(&IID_D3DDEVICE2_OpenGL));
207   fill_opengl_caps(&d1, &d2);
208   return cb((void*)&IID_D3DDEVICE2_OpenGL,"WINE Direct3D2 using OpenGL","direct3d",&d1,&d2,context);
209 }
210
211 int
212 is_OpenGL(
213     REFCLSID rguid, IDirectDrawSurfaceImpl* surface,
214     IDirect3DDevice2Impl** device, IDirect3D2Impl* d3d
215 ) {
216   mesa_d3dd_private *odev = NULL;
217   HDC device_context;
218   XVisualInfo *vis;
219   int num;
220   XVisualInfo template;
221   IDirectDrawSurfaceImpl* surf;
222
223   TRACE("rguid = %s, surface = %p, &device = %p, d3d = %p\n",debugstr_guid(rguid),surface,device,d3d);
224   if (/* Default device */
225       (rguid == NULL) ||
226       /* HAL Device */
227       (!memcmp(&IID_IDirect3DHALDevice,rguid,sizeof(IID_IDirect3DHALDevice))) ||
228       /* OpenGL Device */
229       (!memcmp(&IID_D3DDEVICE2_OpenGL,rguid,sizeof(IID_D3DDEVICE2_OpenGL)))) {
230
231     *device = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DDevice2Impl));
232     (*device)->private = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(mesa_d3dd_private));
233     odev = (mesa_d3dd_private*)(*device)->private;
234     (*device)->ref = 1;
235     ICOM_VTBL(*device) = &OpenGL_vtable;
236     (*device)->d3d = d3d;
237     (*device)->surface = surface;
238     (*device)->viewport_list = NULL;
239     (*device)->current_viewport = NULL;
240     (*device)->current_texture = NULL;
241     (*device)->set_context = set_context;
242
243     TRACE("Creating OpenGL device for surface %p\n", surface);
244     /* Create the OpenGL context */
245     /* First get the correct visual */
246     /* Create the context */
247       
248     device_context = GetDC((*device)->surface->ddraw_owner->window);
249     odev->gdi_display = get_display(device_context);
250     odev->drawable = get_drawable(device_context);
251     ReleaseDC((*device)->surface->ddraw_owner->window,device_context);
252     ENTER_GL();
253
254     template.visualid = (VisualID)GetPropA( GetDesktopWindow(), "__wine_x11_visual_id" );
255     vis = XGetVisualInfo(odev->gdi_display, VisualIDMask, &template, &num);
256     if (vis == NULL)
257       ERR("No visual found !\n");
258     else
259       TRACE("Visual found\n");
260
261     odev->ctx = glXCreateContext(odev->gdi_display, vis,
262                                    NULL, GL_TRUE);
263
264     if (odev->ctx == NULL)
265       ERR("Error in context creation !\n");
266     else
267       TRACE("Context created (%p)\n", odev->ctx);
268
269     /* Look for the front buffer and override its surface's Flip method (if in double buffering) */ 
270     for (surf = surface; surf != NULL; surf = surf->surface_owner)
271         if ((surf->surface_desc.ddsCaps.dwCaps&(DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER))
272             == (DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER))
273         {
274             surface->surface_owner->aux_ctx  = (LPVOID)odev->gdi_display;
275             surface->surface_owner->aux_data = (LPVOID)odev->drawable;
276             surface->surface_owner->aux_flip = opengl_flip;
277             break;
278         }
279
280     odev->rs.src = GL_ONE;
281     odev->rs.dst = GL_ZERO;
282     odev->rs.mag = GL_NEAREST;
283     odev->rs.min = GL_NEAREST;
284     odev->vt     = 0;
285
286     /* Allocate memory for the matrices */
287     odev->world_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
288     odev->view_mat  = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
289     odev->proj_mat  = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
290
291     memcpy(odev->world_mat, id_mat, 16 * sizeof(float));
292     memcpy(odev->view_mat , id_mat, 16 * sizeof(float));
293     memcpy(odev->proj_mat , id_mat, 16 * sizeof(float));
294
295     /* Initialisation */
296     TRACE("Setting current context\n");
297     LEAVE_GL();
298     (*device)->set_context(*device);
299     ENTER_GL();
300     TRACE("Current context set\n");
301     glClearColor(0.0, 0.0, 0.0, 0.0);
302     glColor3f(1.0, 1.0, 1.0);
303     LEAVE_GL();
304
305     fill_device_capabilities(d3d->ddraw);
306
307     TRACE("OpenGL device created \n");
308     return 1;
309   }
310   FIXME("bad IID %s\n",debugstr_guid(rguid));
311   /* This is not the OpenGL UID */
312   return 0;
313 }
314
315 /*******************************************************************************
316  *                              MESA IDirect3DDevice2
317  */
318 static ULONG WINAPI MESA_IDirect3DDevice2Impl_Release(LPDIRECT3DDEVICE2 iface)
319 {
320   ICOM_THIS(IDirect3DDevice2Impl,iface);
321   TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
322
323   if (!--(This->ref)) {
324     D3DDPRIVATE(This);
325
326     ENTER_GL();
327     glXDestroyContext(odev->gdi_display, odev->ctx);
328     LEAVE_GL();
329     HeapFree(GetProcessHeap(),0,This->private);
330     HeapFree(GetProcessHeap(),0,This);
331     return 0;
332   }
333   return This->ref;
334 }
335
336 /*** IDirect3DDevice2 methods ***/
337 static HRESULT WINAPI MESA_IDirect3DDevice2Impl_GetCaps(
338     LPDIRECT3DDEVICE2 iface, LPD3DDEVICEDESC lpdescsoft,
339     LPD3DDEVICEDESC lpdeschard
340 ) {
341   ICOM_THIS(IDirect3DDevice2Impl,iface);
342   FIXME("(%p)->(%p,%p): stub\n", This, lpdescsoft, lpdeschard);
343   fill_opengl_caps(lpdescsoft, lpdeschard);
344   return DD_OK;
345 }
346
347 static HRESULT enum_texture_format_OpenGL(LPD3DENUMTEXTUREFORMATSCALLBACK cb,
348                                           LPVOID context) {
349   DDSURFACEDESC sdesc;
350   LPDDPIXELFORMAT pformat;
351
352   /* Do the texture enumeration */
353   sdesc.dwSize = sizeof(DDSURFACEDESC);
354   sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
355   sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
356   pformat = &(sdesc.ddpfPixelFormat);
357   pformat->dwSize = sizeof(DDPIXELFORMAT);
358   pformat->dwFourCC = 0;
359
360   TRACE("Enumerating GL_RGBA unpacked (32)\n");
361   pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
362   pformat->u1.dwRGBBitCount = 32;
363   pformat->u2.dwRBitMask =         0xFF000000;
364   pformat->u3.dwGBitMask =         0x00FF0000;
365   pformat->u4.dwBBitMask =        0x0000FF00;
366   pformat->u5.dwRGBAlphaBitMask = 0x000000FF;
367   if (cb(&sdesc, context) == 0)
368     return DD_OK;
369
370   TRACE("Enumerating GL_RGB unpacked (24)\n");
371   pformat->dwFlags = DDPF_RGB;
372   pformat->u1.dwRGBBitCount = 24;
373   pformat->u2.dwRBitMask =  0x00FF0000;
374   pformat->u3.dwGBitMask =  0x0000FF00;
375   pformat->u4.dwBBitMask = 0x000000FF;
376   pformat->u5.dwRGBAlphaBitMask = 0x00000000;
377   if (cb(&sdesc, context) == 0)
378     return DD_OK;
379
380 #ifndef HAVE_BUGGY_MESAGL
381   /* The packed texture format are buggy in Mesa. The bug was reported and corrected,
382      so that future version will work great. */
383   TRACE("Enumerating GL_RGB packed GL_UNSIGNED_SHORT_5_6_5 (16)\n");
384   pformat->dwFlags = DDPF_RGB;
385   pformat->u1.dwRGBBitCount = 16;
386   pformat->u2.dwRBitMask =  0x0000F800;
387   pformat->u3.dwGBitMask =  0x000007E0;
388   pformat->u4.dwBBitMask = 0x0000001F;
389   pformat->u5.dwRGBAlphaBitMask = 0x00000000;
390   if (cb(&sdesc, context) == 0)
391     return DD_OK;
392
393   TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_5_5_5_1 (16)\n");
394   pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
395   pformat->u1.dwRGBBitCount = 16;
396   pformat->u2.dwRBitMask =         0x0000F800;
397   pformat->u3.dwGBitMask =         0x000007C0;
398   pformat->u4.dwBBitMask =        0x0000003E;
399   pformat->u5.dwRGBAlphaBitMask = 0x00000001;
400   if (cb(&sdesc, context) == 0)
401     return DD_OK;
402
403   TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_4_4_4_4 (16)\n");
404   pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
405   pformat->u1.dwRGBBitCount = 16;
406   pformat->u2.dwRBitMask =         0x0000F000;
407   pformat->u3.dwGBitMask =         0x00000F00;
408   pformat->u4.dwBBitMask =        0x000000F0;
409   pformat->u5.dwRGBAlphaBitMask = 0x0000000F;
410   if (cb(&sdesc, context) == 0)
411     return DD_OK;
412
413   TRACE("Enumerating GL_RGB packed GL_UNSIGNED_BYTE_3_3_2 (8)\n");
414   pformat->dwFlags = DDPF_RGB;
415   pformat->u1.dwRGBBitCount = 8;
416   pformat->u2.dwRBitMask =        0x000000E0;
417   pformat->u3.dwGBitMask =        0x0000001C;
418   pformat->u4.dwBBitMask =        0x00000003;
419   pformat->u5.dwRGBAlphaBitMask = 0x00000000;
420   if (cb(&sdesc, context) == 0)
421     return DD_OK;
422 #endif
423
424   TRACE("Enumerating GL_ARGB (no direct OpenGL equivalent - conversion needed)\n");
425   pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
426   pformat->u1.dwRGBBitCount = 16;
427   pformat->u2.dwRBitMask =         0x00007C00;
428   pformat->u3.dwGBitMask =         0x000003E0;
429   pformat->u4.dwBBitMask =         0x0000001F;
430   pformat->u5.dwRGBAlphaBitMask =  0x00008000;
431   if (cb(&sdesc, context) == 0)
432     return DD_OK;
433
434   TRACE("Enumerating Paletted (8)\n");
435   pformat->dwFlags = DDPF_PALETTEINDEXED8;
436   pformat->u1.dwRGBBitCount = 8;
437   pformat->u2.dwRBitMask =  0x00000000;
438   pformat->u3.dwGBitMask =  0x00000000;
439   pformat->u4.dwBBitMask = 0x00000000;
440   pformat->u5.dwRGBAlphaBitMask = 0x00000000;
441   if (cb(&sdesc, context) == 0)
442     return DD_OK;
443
444   TRACE("End of enumeration\n");
445
446   return DD_OK;
447 }
448
449 static HRESULT WINAPI MESA_IDirect3DDevice2Impl_EnumTextureFormats(
450     LPDIRECT3DDEVICE2 iface, LPD3DENUMTEXTUREFORMATSCALLBACK cb, LPVOID context
451 ) {
452   ICOM_THIS(IDirect3DDevice2Impl,iface);
453   FIXME("(%p)->(%p,%p): stub\n", This, cb, context);
454
455   return enum_texture_format_OpenGL(cb, context);
456 }
457
458 static HRESULT WINAPI MESA_IDirect3DDevice2Impl_BeginScene(
459     LPDIRECT3DDEVICE2 iface
460 ) {
461   ICOM_THIS(IDirect3DDevice2Impl,iface);
462
463   FIXME("(%p)->(): stub\n", This);
464
465   /* Here, we should get the DDraw surface and 'copy it' to the
466      OpenGL surface.... */
467
468   return DD_OK;
469 }
470
471 HRESULT WINAPI MESA_IDirect3DDevice2Impl_EndScene(LPDIRECT3DDEVICE2 iface) {
472   ICOM_THIS(IDirect3DDevice2Impl,iface);
473
474   FIXME("(%p)->(): stub\n", This);
475
476   /* No need to do anything here... */
477
478   return DD_OK;
479 }
480
481 static HRESULT WINAPI MESA_IDirect3DDevice2Impl_SetRenderState(
482     LPDIRECT3DDEVICE2 iface, D3DRENDERSTATETYPE dwRenderStateType,
483     DWORD dwRenderState
484 ) {
485   ICOM_THIS(IDirect3DDevice2Impl,iface);
486   D3DDPRIVATE(This);
487
488   TRACE("(%p)->(%d,%ld)\n", This, dwRenderStateType, dwRenderState);
489
490   /* Call the render state functions */
491   set_render_state(dwRenderStateType, dwRenderState, &(odev->rs));
492
493   return DD_OK;
494 }
495
496 static HRESULT WINAPI MESA_IDirect3DDevice2Impl_SetLightState(
497     LPDIRECT3DDEVICE2 iface, D3DLIGHTSTATETYPE dwLightStateType,
498     DWORD dwLightState
499 ) {
500   ICOM_THIS(IDirect3DDevice2Impl,iface);
501   FIXME("(%p)->(%d,%08lx): stub\n", This, dwLightStateType, dwLightState);
502
503   switch (dwLightStateType) {
504   case D3DLIGHTSTATE_MATERIAL: {  /* 1 */
505     IDirect3DMaterial2Impl* mat = (IDirect3DMaterial2Impl*) dwLightState;
506
507     if (mat != NULL) {
508       ENTER_GL();
509       mat->activate(mat);
510       LEAVE_GL();
511     } else {
512       TRACE("Zoups !!!\n");
513     }
514   } break;
515
516   case D3DLIGHTSTATE_AMBIENT: {   /* 2 */
517     float light[4];
518
519     light[0] = ((dwLightState >> 16) & 0xFF) / 255.0;
520     light[1] = ((dwLightState >>  8) & 0xFF) / 255.0;
521     light[2] = ((dwLightState >>  0) & 0xFF) / 255.0;
522     light[3] = 1.0;
523     ENTER_GL();
524     glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (float *) light);
525     LEAVE_GL();
526   } break;
527
528 #define UNSUP(x) case D3DLIGHTSTATE_##x: FIXME("unsupported D3DLIGHTSTATE_" #x "!\n");break;
529   UNSUP(COLORMODEL);
530   UNSUP(FOGMODE);
531   UNSUP(FOGSTART);
532   UNSUP(FOGEND);
533   UNSUP(FOGDENSITY);
534 #undef UNSUP
535   default:
536     TRACE("Unexpected Light State Type\n");
537     return DDERR_INVALIDPARAMS;
538   }
539
540   return DD_OK;
541 }
542
543 static HRESULT WINAPI MESA_IDirect3DDevice2Impl_SetTransform(
544     LPDIRECT3DDEVICE2 iface, D3DTRANSFORMSTATETYPE d3dts,
545     LPD3DMATRIX lpmatrix
546 ) {
547   ICOM_THIS(IDirect3DDevice2Impl,iface);
548   D3DDPRIVATE(This);
549
550   FIXME("(%p)->(%d,%p): stub\n", This, d3dts, lpmatrix);
551
552   ENTER_GL();
553
554   /* Using a trial and failure approach, I found that the order of
555      Direct3D transformations that works best is :
556
557      ScreenCoord = ProjectionMat * ViewMat * WorldMat * ObjectCoord
558
559      As OpenGL uses only two matrices, I combined PROJECTION and VIEW into
560      OpenGL's GL_PROJECTION matrix and the WORLD into GL_MODELVIEW.
561
562      If anyone has a good explanation of the three different matrices in
563      the SDK online documentation, feel free to point it to me. For example,
564      which matrices transform lights ? In OpenGL only the PROJECTION matrix
565      transform the lights, not the MODELVIEW. Using the matrix names, I
566      supposed that PROJECTION and VIEW (all 'camera' related names) do
567      transform lights, but WORLD do not. It may be wrong though... */
568
569   /* After reading through both OpenGL and Direct3D documentations, I
570      thought that D3D matrices were written in 'line major mode' transposed
571      from OpenGL's 'column major mode'. But I found out that a simple memcpy
572      works fine to transfer one matrix format to the other (it did not work
573      when transposing)....
574
575      So :
576       1) are the documentations wrong
577       2) does the matrix work even if they are not read correctly
578       3) is Mesa's implementation of OpenGL not compliant regarding Matrix
579          loading using glLoadMatrix ?
580
581      Anyway, I always use 'conv_mat' to transfer the matrices from one format
582      to the other so that if I ever find out that I need to transpose them, I
583      will able to do it quickly, only by changing the macro conv_mat. */
584
585   switch (d3dts) {
586   case D3DTRANSFORMSTATE_WORLD: {
587     conv_mat(lpmatrix, odev->world_mat);
588     glMatrixMode(GL_MODELVIEW);
589     glLoadMatrixf((float *) odev->world_mat);
590   } break;
591
592   case D3DTRANSFORMSTATE_VIEW: {
593     conv_mat(lpmatrix, odev->view_mat);
594     glMatrixMode(GL_PROJECTION);
595     glLoadMatrixf((float *) odev->proj_mat);
596     glMultMatrixf((float *) odev->view_mat);
597   } break;
598
599   case D3DTRANSFORMSTATE_PROJECTION: {
600     conv_mat(lpmatrix, odev->proj_mat);
601     glMatrixMode(GL_PROJECTION);
602     glLoadMatrixf((float *) odev->proj_mat);
603     glMultMatrixf((float *) odev->view_mat);
604   } break;
605
606   default:
607     break;
608   }
609   LEAVE_GL();
610   return DD_OK;
611 }
612
613 #define DRAW_PRIMITIVE(MAXVERT,INDEX)                                   \
614   /* Puts GL in the correct lighting mode */                            \
615   if (odev->vt != d3dv) {                                               \
616     if (odev->vt == D3DVT_TLVERTEX) {                                   \
617       /* Need to put the correct transformation again */                \
618       glMatrixMode(GL_MODELVIEW);                                       \
619       glLoadMatrixf((float *) odev->world_mat);                      \
620       glMatrixMode(GL_PROJECTION);                                      \
621       glLoadMatrixf((float *) odev->proj_mat);                  \
622       glMultMatrixf((float *) odev->view_mat);                  \
623     }                                                                   \
624                                                                         \
625     switch (d3dv) {                                                     \
626     case D3DVT_VERTEX:                                                  \
627       TRACE("Standard Vertex\n");                                       \
628       glEnable(GL_LIGHTING);                                            \
629       break;                                                            \
630                                                                         \
631     case D3DVT_LVERTEX:                                                 \
632       TRACE("Lighted Vertex\n");                                        \
633       glDisable(GL_LIGHTING);                                           \
634       break;                                                            \
635                                                                         \
636     case D3DVT_TLVERTEX: {                                              \
637       GLdouble height, width, minZ, maxZ;                               \
638                                                                         \
639       TRACE("Transformed - Lighted Vertex\n");                          \
640       /* First, disable lighting */                                     \
641       glDisable(GL_LIGHTING);                                           \
642                                                                         \
643       /* Then do not put any transformation matrixes */                 \
644       glMatrixMode(GL_MODELVIEW);                                       \
645       glLoadIdentity();                                                 \
646       glMatrixMode(GL_PROJECTION);                                      \
647       glLoadIdentity();                                                 \
648                                                                         \
649       if (This->current_viewport == NULL) {                             \
650         ERR("No current viewport !\n");                                 \
651         /* Using standard values */                                     \
652         height = 640.0;                                                 \
653         width = 480.0;                                                  \
654         minZ = -10.0;                                                   \
655         maxZ = 10.0;                                                    \
656       } else {                                                          \
657         if (This->current_viewport->use_vp2) {                          \
658           height = (GLdouble) This->current_viewport->viewport.vp2.dwHeight;\
659           width  = (GLdouble) This->current_viewport->viewport.vp2.dwWidth;\
660           minZ   = (GLdouble) This->current_viewport->viewport.vp2.dvMinZ;\
661           maxZ   = (GLdouble) This->current_viewport->viewport.vp2.dvMaxZ;\
662         } else {                                                        \
663           height = (GLdouble) This->current_viewport->viewport.vp1.dwHeight;\
664           width  = (GLdouble) This->current_viewport->viewport.vp1.dwWidth;\
665           minZ   = (GLdouble) This->current_viewport->viewport.vp1.dvMinZ;\
666           maxZ   = (GLdouble) This->current_viewport->viewport.vp1.dvMaxZ;\
667         }                                                               \
668       }                                                                 \
669                                                                         \
670       glOrtho(0.0, width, height, 0.0, -minZ, -maxZ);                   \
671     } break;                                                            \
672                                                                         \
673     default:                                                            \
674       ERR("Unhandled vertex type\n");                                   \
675       break;                                                            \
676     }                                                                   \
677                                                                         \
678     odev->vt = d3dv;                                                    \
679   }                                                                     \
680                                                                         \
681   switch (d3dp) {                                                       \
682   case D3DPT_POINTLIST:                                                 \
683     TRACE("Start POINTS\n");                                            \
684     glBegin(GL_POINTS);                                                 \
685     break;                                                              \
686                                                                         \
687   case D3DPT_LINELIST:                                                  \
688     TRACE("Start LINES\n");                                             \
689     glBegin(GL_LINES);                                                  \
690     break;                                                              \
691                                                                         \
692   case D3DPT_LINESTRIP:                                                 \
693     TRACE("Start LINE_STRIP\n");                                        \
694     glBegin(GL_LINE_STRIP);                                             \
695     break;                                                              \
696                                                                         \
697   case D3DPT_TRIANGLELIST:                                              \
698     TRACE("Start TRIANGLES\n");                                         \
699     glBegin(GL_TRIANGLES);                                              \
700     break;                                                              \
701                                                                         \
702   case D3DPT_TRIANGLESTRIP:                                             \
703     TRACE("Start TRIANGLE_STRIP\n");                                    \
704     glBegin(GL_TRIANGLE_STRIP);                                         \
705     break;                                                              \
706                                                                         \
707   case D3DPT_TRIANGLEFAN:                                               \
708     TRACE("Start TRIANGLE_FAN\n");                                      \
709     glBegin(GL_TRIANGLE_FAN);                                           \
710     break;                                                              \
711                                                                         \
712   default:                                                              \
713     TRACE("Unhandled primitive\n");                                     \
714     break;                                                              \
715   }                                                                     \
716                                                                         \
717   /* Draw the primitives */                                             \
718   for (vx_index = 0; vx_index < MAXVERT; vx_index++) {                  \
719     switch (d3dv) {                                                     \
720     case D3DVT_VERTEX: {                                                \
721       D3DVERTEX *vx = ((D3DVERTEX *) lpvertex) + INDEX;                 \
722                                                                         \
723       glNormal3f(vx->u4.nx, vx->u5.ny, vx->u6.nz);                      \
724       glVertex3f(vx->u1.x, vx->u2.y, vx->u3.z);                         \
725       TRACE("   V: %f %f %f\n", vx->u1.x, vx->u2.y, vx->u3.z);          \
726     } break;                                                            \
727                                                                         \
728     case D3DVT_LVERTEX: {                                               \
729       D3DLVERTEX *vx = ((D3DLVERTEX *) lpvertex) + INDEX;               \
730       DWORD col = vx->u4.color;                                         \
731                                                                         \
732       glColor3f(((col >> 16) & 0xFF) / 255.0,                           \
733                 ((col >>  8) & 0xFF) / 255.0,                           \
734                 ((col >>  0) & 0xFF) / 255.0);                          \
735       glVertex3f(vx->u1.x, vx->u2.y, vx->u3.z);                         \
736       TRACE("  LV: %f %f %f (%02lx %02lx %02lx)\n",                     \
737             vx->u1.x, vx->u2.y, vx->u3.z,                               \
738             ((col >> 16) & 0xFF), ((col >>  8) & 0xFF), ((col >>  0) & 0xFF));\
739     } break;                                                            \
740                                                                         \
741     case D3DVT_TLVERTEX: {                                              \
742       D3DTLVERTEX *vx = ((D3DTLVERTEX *) lpvertex) + INDEX;             \
743       DWORD col = vx->u5.color;                                         \
744                                                                         \
745       glColor3f(((col >> 16) & 0xFF) / 255.0,                           \
746                 ((col >>  8) & 0xFF) / 255.0,                           \
747                 ((col >>  0) & 0xFF) / 255.0);                          \
748       glTexCoord2f(vx->u7.tu, vx->u8.tv);                               \
749       if (vx->u4.rhw < 0.01)                                            \
750         glVertex3f(vx->u1.sx,                                           \
751                    vx->u2.sy,                                           \
752                    vx->u3.sz);                                          \
753       else                                                              \
754         glVertex4f(vx->u1.sx / vx->u4.rhw,                              \
755                    vx->u2.sy / vx->u4.rhw,                              \
756                    vx->u3.sz / vx->u4.rhw,                              \
757                    1.0 / vx->u4.rhw);                                   \
758       TRACE(" TLV: %f %f %f (%02lx %02lx %02lx) (%f %f) (%f)\n",        \
759             vx->u1.sx, vx->u2.sy, vx->u3.sz,                            \
760             ((col >> 16) & 0xFF), ((col >>  8) & 0xFF), ((col >>  0) & 0xFF),\
761             vx->u7.tu, vx->u8.tv, vx->u4.rhw);                          \
762     } break;                                                            \
763                                                                         \
764     default:                                                            \
765       FIXME("Unhandled vertex type\n");                                 \
766       break;                                                            \
767     }                                                                   \
768   }                                                                     \
769                                                                         \
770   glEnd();                                                              \
771   TRACE("End\n");
772
773
774 static HRESULT WINAPI MESA_IDirect3DDevice2Impl_DrawPrimitive(
775     LPDIRECT3DDEVICE2 iface, D3DPRIMITIVETYPE d3dp, D3DVERTEXTYPE d3dv,
776     LPVOID lpvertex, DWORD vertcount, DWORD dwFlags
777 ) {
778   ICOM_THIS(IDirect3DDevice2Impl,iface);
779   D3DDPRIVATE(This);
780   int vx_index;
781
782   TRACE("(%p)->(%d,%d,%p,%ld,%08lx): stub\n", This, d3dp, d3dv, lpvertex, vertcount, dwFlags);
783
784   ENTER_GL();
785   DRAW_PRIMITIVE(vertcount, vx_index);
786   LEAVE_GL();
787
788   return D3D_OK;
789 }
790
791 static HRESULT WINAPI MESA_IDirect3DDevice2Impl_DrawIndexedPrimitive(
792     LPDIRECT3DDEVICE2 iface, D3DPRIMITIVETYPE d3dp, D3DVERTEXTYPE d3dv,
793     LPVOID lpvertex, DWORD vertcount, LPWORD lpindexes, DWORD indexcount,
794     DWORD dwFlags
795 ) {
796   ICOM_THIS(IDirect3DDevice2Impl,iface);
797   D3DDPRIVATE(This);
798   int vx_index;
799
800   TRACE("(%p)->(%d,%d,%p,%ld,%p,%ld,%08lx): stub\n", This, d3dp, d3dv, lpvertex, vertcount, lpindexes, indexcount, dwFlags);
801
802   ENTER_GL();
803   DRAW_PRIMITIVE(indexcount, lpindexes[vx_index]);
804   LEAVE_GL();
805
806   return D3D_OK;
807 }
808
809 static HRESULT WINAPI MESA_IDirect3DDeviceImpl_CreateExecuteBuffer(
810     LPDIRECT3DDEVICE iface, LPD3DEXECUTEBUFFERDESC lpDesc,
811     LPDIRECT3DEXECUTEBUFFER *lplpDirect3DExecuteBuffer, IUnknown *pUnkOuter
812 ) {
813     ICOM_THIS(IDirect3DDeviceImpl,iface);
814     TRACE("(%p)->(%p,%p,%p)\n", This, lpDesc, lplpDirect3DExecuteBuffer, pUnkOuter);
815     *lplpDirect3DExecuteBuffer = d3dexecutebuffer_create(This, lpDesc);
816     return DD_OK;
817 }
818
819
820 /*******************************************************************************
821  *                              OpenGL-specific IDirect3DDevice2
822  */
823
824 /*******************************************************************************
825  *                              OpenGL-specific VTable
826  */
827
828 ICOM_VTABLE(IDirect3DDevice2) OpenGL_vtable =
829 {
830   ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
831   IDirect3DDevice2Impl_QueryInterface,
832   IDirect3DDevice2Impl_AddRef,
833   MESA_IDirect3DDevice2Impl_Release,
834   /*** IDirect3DDevice2 methods ***/
835   MESA_IDirect3DDevice2Impl_GetCaps,
836   IDirect3DDevice2Impl_SwapTextureHandles,
837   IDirect3DDevice2Impl_GetStats,
838   IDirect3DDevice2Impl_AddViewport,
839   IDirect3DDevice2Impl_DeleteViewport,
840   IDirect3DDevice2Impl_NextViewport,
841   MESA_IDirect3DDevice2Impl_EnumTextureFormats,
842   MESA_IDirect3DDevice2Impl_BeginScene,
843   MESA_IDirect3DDevice2Impl_EndScene,
844   IDirect3DDevice2Impl_GetDirect3D,
845
846   /*** DrawPrimitive API ***/
847   IDirect3DDevice2Impl_SetCurrentViewport,
848   IDirect3DDevice2Impl_GetCurrentViewport,
849
850   IDirect3DDevice2Impl_SetRenderTarget,
851   IDirect3DDevice2Impl_GetRenderTarget,
852
853   IDirect3DDevice2Impl_Begin,
854   IDirect3DDevice2Impl_BeginIndexed,
855   IDirect3DDevice2Impl_Vertex,
856   IDirect3DDevice2Impl_Index,
857   IDirect3DDevice2Impl_End,
858
859   IDirect3DDevice2Impl_GetRenderState,
860   MESA_IDirect3DDevice2Impl_SetRenderState,
861   IDirect3DDevice2Impl_GetLightState,
862   MESA_IDirect3DDevice2Impl_SetLightState,
863   MESA_IDirect3DDevice2Impl_SetTransform,
864   IDirect3DDevice2Impl_GetTransform,
865   IDirect3DDevice2Impl_MultiplyTransform,
866
867   MESA_IDirect3DDevice2Impl_DrawPrimitive,
868   MESA_IDirect3DDevice2Impl_DrawIndexedPrimitive,
869
870   IDirect3DDevice2Impl_SetClipStatus,
871   IDirect3DDevice2Impl_GetClipStatus,
872 };
873
874 /*******************************************************************************
875  *                              Direct3DDevice
876  */
877 int d3d_OpenGL_dx3(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) {
878   D3DDEVICEDESC d1,d2;
879
880   TRACE(" Enumerating OpenGL D3D device (IID %s).\n", debugstr_guid(&IID_D3DDEVICE_OpenGL));
881
882   fill_opengl_caps(&d1, &d2);
883
884   return cb((void*)&IID_D3DDEVICE_OpenGL,"WINE Direct3D using OpenGL","direct3d",&d1,&d2,context);
885 }
886
887 int is_OpenGL_dx3(REFCLSID rguid, IDirectDrawSurfaceImpl* surface, IDirect3DDeviceImpl** device)
888 {
889   TRACE("rguid = %s, surface = %p, &device = %p\n",debugstr_guid(rguid),surface,device);
890   if (!memcmp(&IID_D3DDEVICE_OpenGL,rguid,sizeof(IID_D3DDEVICE_OpenGL))) {
891     mesa_d3dd_private *odev;
892     HDC device_context;
893     int attributeList[]={ GLX_RGBA, GLX_DEPTH_SIZE, 16, GLX_DOUBLEBUFFER, None };
894     XVisualInfo *xvis;
895     IDirectDrawSurfaceImpl* surf;
896
897     *device = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DDeviceImpl));
898     (*device)->private = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(mesa_d3dd_private));
899     odev = (mesa_d3dd_private*)(*device)->private;
900     (*device)->ref = 1;
901     ICOM_VTBL(*device) = &OpenGL_vtable_dx3;
902     (*device)->d3d = NULL;
903     (*device)->surface = surface;
904
905     (*device)->viewport_list = NULL;
906     (*device)->current_viewport = NULL;
907     (*device)->current_texture = NULL;
908
909     (*device)->set_context = (void*)set_context;
910
911     TRACE("OpenGL device created \n");
912
913     /* Create the OpenGL context */
914     /* First get the correct visual */
915     /* if (surface->s.backbuffer == NULL)
916        attributeList[3] = None; */
917     device_context = GetDC((*device)->surface->ddraw_owner->window);
918     odev->gdi_display = get_display(device_context);
919     odev->drawable = get_drawable(device_context);
920     ReleaseDC((*device)->surface->ddraw_owner->window,device_context);
921     ENTER_GL();
922     xvis = glXChooseVisual(odev->gdi_display,
923                            DefaultScreen(odev->gdi_display),
924                            attributeList);
925     if (xvis == NULL)
926       ERR("No visual found !\n");
927     else
928       TRACE("Visual found\n");
929     
930     /* Create the context */
931     odev->ctx = glXCreateContext(odev->gdi_display,
932                                  xvis,
933                                  NULL,
934                                  GL_TRUE);
935     TRACE("Context created\n");
936
937     /* Look for the front buffer and override its surface's Flip method (if in double buffering) */ 
938     for (surf = surface; surf != NULL; surf = surf->surface_owner)
939         if ((surf->surface_desc.ddsCaps.dwCaps&(DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER))
940             == (DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER))
941         {
942             surface->surface_owner->aux_ctx  = (LPVOID)odev->gdi_display;
943             surface->surface_owner->aux_data = (LPVOID)odev->drawable;
944             surface->surface_owner->aux_flip = opengl_flip;
945             break;
946         }
947         
948     odev->rs.src = GL_ONE;
949     odev->rs.dst = GL_ZERO;
950     odev->rs.mag = GL_NEAREST;
951     odev->rs.min = GL_NEAREST;
952
953     odev->world_mat = (LPD3DMATRIX) &id_mat;
954     odev->view_mat  = (LPD3DMATRIX) &id_mat;
955     odev->proj_mat  = (LPD3DMATRIX) &id_mat;
956
957     /* Initialisation */
958     LEAVE_GL();
959     (*device)->set_context(*device);
960     ENTER_GL();
961     glClearColor(0.0, 0.0, 0.0, 0.0);
962     glColor3f(1.0, 1.0, 1.0);
963     LEAVE_GL();
964     fill_device_capabilities((IDirectDrawImpl *) surface->ddraw_owner);
965
966     return 1;
967   }
968
969   /* This is not the OpenGL UID */
970   return DD_OK;
971 }
972
973 static ULONG WINAPI MESA_IDirect3DDeviceImpl_Release(LPDIRECT3DDEVICE iface)
974 {
975   ICOM_THIS(IDirect3DDeviceImpl,iface);
976   TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
977
978   if (!--(This->ref)) {
979     D3DDPRIVATE(This);
980     ENTER_GL();
981     glXDestroyContext(odev->gdi_display, odev->ctx);
982     LEAVE_GL();
983     HeapFree(GetProcessHeap(),0,This->private);
984     HeapFree(GetProcessHeap(),0,This);
985     return 0;
986   }
987   return This->ref;
988 }
989
990 static HRESULT WINAPI MESA_IDirect3DDeviceImpl_EnumTextureFormats(
991     LPDIRECT3DDEVICE iface,LPD3DENUMTEXTUREFORMATSCALLBACK lpd3dEnumTextureProc,
992     LPVOID lpArg)
993 {
994   ICOM_THIS(IDirect3DDeviceImpl,iface);
995   TRACE("(%p)->(%p,%p): stub\n", This, lpd3dEnumTextureProc, lpArg);
996
997   return enum_texture_format_OpenGL(lpd3dEnumTextureProc, lpArg);
998 }
999
1000
1001 static HRESULT WINAPI MESA_IDirect3DDeviceImpl_BeginScene(LPDIRECT3DDEVICE iface)
1002 {
1003   ICOM_THIS(IDirect3DDeviceImpl,iface);
1004   /* OpenGL_IDirect3DDevice *odev = (OpenGL_IDirect3DDevice *) This; */
1005
1006   FIXME("(%p)->(): stub\n", This);
1007
1008   /* We get the pointer to the surface (should be done on flip) */
1009   /* odev->zb->pbuf = This->surface->s.surface_desc.u2.lpSurface; */
1010
1011   return DD_OK;
1012 }
1013
1014
1015 /* This is for the moment copy-pasted from IDirect3DDevice2...
1016    Will make a common function ... */
1017 static HRESULT WINAPI MESA_IDirect3DDeviceImpl_EndScene(LPDIRECT3DDEVICE iface)
1018 {
1019   ICOM_THIS(IDirect3DDeviceImpl,iface);
1020
1021   FIXME("(%p)->(): stub\n", This);
1022
1023   /* No need to do anything here... */
1024
1025   return DD_OK;
1026 }
1027
1028 /*******************************************************************************
1029  *                              Direct3DDevice VTable
1030  */
1031 ICOM_VTABLE(IDirect3DDevice) OpenGL_vtable_dx3 =
1032 {
1033   ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1034   IDirect3DDeviceImpl_QueryInterface,
1035   IDirect3DDeviceImpl_AddRef,
1036   MESA_IDirect3DDeviceImpl_Release,
1037   IDirect3DDeviceImpl_Initialize,
1038   IDirect3DDeviceImpl_GetCaps,
1039   IDirect3DDeviceImpl_SwapTextureHandles,
1040   MESA_IDirect3DDeviceImpl_CreateExecuteBuffer,
1041   IDirect3DDeviceImpl_GetStats,
1042   IDirect3DDeviceImpl_Execute,
1043   IDirect3DDeviceImpl_AddViewport,
1044   IDirect3DDeviceImpl_DeleteViewport,
1045   IDirect3DDeviceImpl_NextViewport,
1046   IDirect3DDeviceImpl_Pick,
1047   IDirect3DDeviceImpl_GetPickRecords,
1048   MESA_IDirect3DDeviceImpl_EnumTextureFormats,
1049   IDirect3DDeviceImpl_CreateMatrix,
1050   IDirect3DDeviceImpl_SetMatrix,
1051   IDirect3DDeviceImpl_GetMatrix,
1052   IDirect3DDeviceImpl_DeleteMatrix,
1053   MESA_IDirect3DDeviceImpl_BeginScene,
1054   MESA_IDirect3DDeviceImpl_EndScene,
1055   IDirect3DDeviceImpl_GetDirect3D,
1056 };