Replaced all the Mesa specific code by GLX code. Should work now on

any OpenGL implementation.
This commit is contained in:
Lionel Ulmer 1999-05-13 18:53:05 +00:00 committed by Alexandre Julliard
parent 75793af6d1
commit ad7258517e
12 changed files with 241 additions and 30 deletions

View File

@ -4,34 +4,36 @@ Introduction
This file contains information about Wine's implementation of This file contains information about Wine's implementation of
Direct3D. Direct3D.
The current version requires : The current version has been tested using Mesa. For optimal
* Mesa (tested with version 3.1 beta) performances, you need at least Mesa 3.1 beta 2.
* a display in 16bpp
To minimize the impact on DirectDraw (i.e. to reuse most of the code
already done for DirectDraw), I decided not to start with an
implementation based on GLX, but on OSMesa. This way, all the OpenGL
rendering are done in a 'private' memory buffer, buffer that will
copied back to the DirectDraw Surface each time a 3D scene
finishes. It is not optimal for execution speed (on each frame, the
OpenGL buffer is converted from 32 to 16 bpp and copied onto the
screen) but is for development (I had almost nothing to change in
DirectDraw). Moreover, 99 % of the code in the Direct3D implementation
is 'device independant' (i.e. GLX / OSMesa / whatever), so that
changing to GLX will have only a minor impact on Direct3D's code.
Where to find Mesa : Where to find Mesa :
-------------------- --------------------
The home of Mesa should soon be http://www.mesa3d.org/ The home of Mesa should soon be http://www.mesa3d.org/
But for now, check http://www.ssec.wisc.edu/~brianp/Mesa.html
For precompiled RPMs, use AltaVista or FTPSearch, but I prefer to 'Use For precompiled RPMs, use AltaVista or FTPSearch, but I prefer to 'Use
the Source' :-) the Source' :-)
WARNING : if you experience crashes in D3DTexture2_Load, see file WARNING : if you experience crashes in D3DTexture2_Load, see file
d3dtexture.c for a 'cure'. You could also patch your version of Mesa d3dtexture.c for a 'cure'. You could also patch your version of Mesa
or wait for version 3.2b (that should have the bug corrected). or get version 3.1 beta 2 or the latest CVS version.
How to configure Mesa :
-----------------------
For Mesa version > 3.1b2, you can configure the Voodoo driver to not
override the signal handlers (something that Wine does really not
like).
For that add the following lines to the /etc/mesa.conf file :
;; Profile for Wine
(config-mesa wine
((fx-catch-signals false)))
And do a 'export MESA_CONFIG=wine' before starting Wine.
Code structure Code structure
-------------- --------------
@ -50,10 +52,15 @@ Some programs with which I tested the code :
* TWIST.EXE (DX3.0) : vertex transformation works as it * TWIST.EXE (DX3.0) : vertex transformation works as it
should. Texturing and lighting still off. should. Texturing and lighting still off.
* Tomb Raider II (DX5.0) : works perfectly (but slowly). All the * Tomb Raider II (DX5.0) : works perfectly (but slowly) in software
calls needed to make TR2 work have been written. mode. All the calls needed to make TR2 work have been written. In
3D accelerated mode with a Voodoo board, it works fine except for
color keying (no transparent textures :/). This is being
investigated with the Mesa authors.
* Jedi Knight (DX3.0) : does not start * Jedi Knight Demo (DX3.0) : works well with the old OSMesa
code. Works for the new GLX code but without the 'head-up' display
(because it is blitted directly on the frame-buffer :/)
* Shadow of the Empire demo (DX3.0) : displays a mangled intro screen * Shadow of the Empire demo (DX3.0) : displays a mangled intro screen
(only blue squares on the screen) (only blue squares on the screen)
@ -61,13 +68,12 @@ Some programs with which I tested the code :
* Forsaken Demo : starts to work. Texturing is missing and it is * Forsaken Demo : starts to work. Texturing is missing and it is
really really slow. really really slow.
* Grim Fandango (DX ?, seems to be 3.0 !!) : does not start. * Grim Fandango (DX 3.0 !!) : works in DDraw mode. Some problems in
D3D mode as it does direct Z Buffer writing.
TODO TODO
---- ----
* work on optimizing Execute Buffers (i.e. Direct3D 3.0) * work on optimizing Execute Buffers (i.e. Direct3D 3.0)
* real GLX implementation (will need a complete rewrite of DirectDraw
also) to have 3DFx support
* restructuration of all the DDRAW.DLL (put that in the dll * restructuration of all the DDRAW.DLL (put that in the dll
directory, better separation of 'drivers, ...) directory, better separation of 'drivers, ...)
* start looking into DirectX 6.0 * start looking into DirectX 6.0
@ -78,4 +84,4 @@ TODO
-- --
Lionel Ulmer - ulmer@directprovider.net Lionel Ulmer - ulmer@directprovider.net
Last updated : Tue Jan 19 1999 Last updated : Sat May 08 1999

View File

@ -10,6 +10,10 @@
#include "wine_gl.h" #include "wine_gl.h"
#include "d3d.h" #include "d3d.h"
#include "x11drv.h"
#undef USE_OSMESA
/***************************************************************************** /*****************************************************************************
* Predeclare the interface implementation structures * Predeclare the interface implementation structures
*/ */
@ -228,6 +232,13 @@ struct IDirect3DDevice2Impl
#ifdef HAVE_MESAGL #ifdef HAVE_MESAGL
#ifdef USE_OSMESA
#define LEAVE_GL() ;
#define ENTER_GL() ;
#else
#define LEAVE_GL() LeaveCriticalSection( &X11DRV_CritSection )
#define ENTER_GL() EnterCriticalSection( &X11DRV_CritSection )
#endif
/* Matrix copy WITH transposition */ /* Matrix copy WITH transposition */
#define conv_mat2(mat,gl_mat) \ #define conv_mat2(mat,gl_mat) \
@ -281,8 +292,12 @@ typedef struct OpenGL_IDirect3DDevice2 {
IDirect3DDevice2Impl common; IDirect3DDevice2Impl common;
/* These are the OpenGL-specific variables */ /* These are the OpenGL-specific variables */
#ifdef USE_OSMESA
OSMesaContext ctx; OSMesaContext ctx;
unsigned char *buffer; unsigned char *buffer;
#else
GLXContext ctx;
#endif
/* The current render state */ /* The current render state */
RenderState rs; RenderState rs;
@ -299,8 +314,12 @@ typedef struct OpenGL_IDirect3DDevice {
IDirect3DDeviceImpl common; IDirect3DDeviceImpl common;
/* These are the OpenGL-specific variables */ /* These are the OpenGL-specific variables */
#ifdef USE_OSMESA
OSMesaContext ctx; OSMesaContext ctx;
unsigned char *buffer; unsigned char *buffer;
#else
GLXContext ctx;
#endif
/* The current render state */ /* The current render state */
RenderState rs; RenderState rs;

View File

@ -122,6 +122,8 @@ void set_render_state(D3DRENDERSTATETYPE dwRenderStateType,
(dwRenderStateType <= D3DRENDERSTATE_STIPPLEPATTERN31)) { (dwRenderStateType <= D3DRENDERSTATE_STIPPLEPATTERN31)) {
ERR(ddraw, "Unhandled stipple !\n"); ERR(ddraw, "Unhandled stipple !\n");
} else { } else {
ENTER_GL();
/* All others state variables */ /* All others state variables */
switch (dwRenderStateType) { switch (dwRenderStateType) {
@ -338,6 +340,8 @@ void set_render_state(D3DRENDERSTATETYPE dwRenderStateType,
ERR(ddraw, "Unhandled Render State\n"); ERR(ddraw, "Unhandled Render State\n");
break; break;
} }
LEAVE_GL();
} }
} }

View File

@ -21,7 +21,7 @@ DEFAULT_DEBUG_CHANNEL(ddraw)
/* Define this variable if you have an unpatched Mesa 3.0 (patches are available /* Define this variable if you have an unpatched Mesa 3.0 (patches are available
on Mesa's home page) or version 3.1b. on Mesa's home page) or version 3.1b.
Version 3.2b should correct this bug */ Version 3.1b2 should correct this bug */
#undef HAVE_BUGGY_MESAGL #undef HAVE_BUGGY_MESAGL
#ifdef HAVE_MESAGL #ifdef HAVE_MESAGL
@ -50,19 +50,36 @@ static ICOM_VTABLE(IDirect3DDevice) OpenGL_vtable_dx3;
static void set_context(IDirect3DDevice2Impl* This) { static void set_context(IDirect3DDevice2Impl* This) {
OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) This; OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) This;
#ifdef USE_OSMESA
OSMesaMakeCurrent(odev->ctx, odev->buffer, OSMesaMakeCurrent(odev->ctx, odev->buffer,
GL_UNSIGNED_BYTE, GL_UNSIGNED_BYTE,
This->surface->s.surface_desc.dwWidth, This->surface->s.surface_desc.dwWidth,
This->surface->s.surface_desc.dwHeight); This->surface->s.surface_desc.dwHeight);
#else
if (glXMakeCurrent(display,
odev->common.surface->s.ddraw->d.drawable,
odev->ctx) == False) {
ERR(ddraw, "Error in setting current context (context %p drawable %d)!\n",
odev->ctx, odev->common.surface->s.ddraw->d.drawable);
}
#endif
} }
static void set_context_dx3(IDirect3DDeviceImpl* This) { static void set_context_dx3(IDirect3DDeviceImpl* This) {
OpenGL_IDirect3DDevice *odev = (OpenGL_IDirect3DDevice *) This; OpenGL_IDirect3DDevice *odev = (OpenGL_IDirect3DDevice *) This;
#ifdef USE_OSMESA
OSMesaMakeCurrent(odev->ctx, odev->buffer, OSMesaMakeCurrent(odev->ctx, odev->buffer,
GL_UNSIGNED_BYTE, GL_UNSIGNED_BYTE,
This->surface->s.surface_desc.dwWidth, This->surface->s.surface_desc.dwWidth,
This->surface->s.surface_desc.dwHeight); This->surface->s.surface_desc.dwHeight);
#else
if (glXMakeCurrent(display,
odev->common.surface->s.ddraw->d.drawable,
odev->ctx) == False) {
ERR(ddraw, "Error in setting current context !\n");
}
#endif
} }
static void fill_opengl_primcaps(D3DPRIMCAPS *pc) static void fill_opengl_primcaps(D3DPRIMCAPS *pc)
@ -150,6 +167,10 @@ int is_OpenGL(REFCLSID rguid, IDirectDrawSurfaceImpl* surface, IDirect3DDevice2I
0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0 0.0, 0.0, 0.0, 1.0
}; };
#ifndef USE_OSMESA
int attributeList[]={ GLX_RGBA, GLX_DEPTH_SIZE, 16, GLX_DOUBLEBUFFER, None };
XVisualInfo *xvis;
#endif
*device = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(OpenGL_IDirect3DDevice2)); *device = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(OpenGL_IDirect3DDevice2));
odev = (OpenGL_IDirect3DDevice2 *) (*device); odev = (OpenGL_IDirect3DDevice2 *) (*device);
@ -163,12 +184,41 @@ int is_OpenGL(REFCLSID rguid, IDirectDrawSurfaceImpl* surface, IDirect3DDevice2I
(*device)->set_context = set_context; (*device)->set_context = set_context;
TRACE(ddraw, "OpenGL device created \n"); TRACE(ddraw, "Creating OpenGL device for surface %p\n", surface);
/* Create the OpenGL context */ /* Create the OpenGL context */
#ifdef USE_OSMESA
odev->ctx = OSMesaCreateContext(OSMESA_RGBA, NULL); odev->ctx = OSMesaCreateContext(OSMESA_RGBA, NULL);
odev->buffer = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, odev->buffer = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
surface->s.surface_desc.dwWidth * surface->s.surface_desc.dwHeight * 4); surface->s.surface_desc.dwWidth * surface->s.surface_desc.dwHeight * 4);
#else
/* First get the correct visual */
TRACE(ddraw, "Backbuffer : %d\n", surface->s.backbuffer == NULL);
/* if (surface->s.backbuffer == NULL)
attributeList[3] = None; */
ENTER_GL();
xvis = glXChooseVisual(display,
DefaultScreen(display),
attributeList);
if (xvis == NULL)
ERR(ddraw, "No visual found !\n");
else
TRACE(ddraw, "Visual found\n");
/* Create the context */
odev->ctx = glXCreateContext(display,
xvis,
NULL,
GL_TRUE);
if (odev->ctx == NULL)
ERR(ddraw, "Error in context creation !\n");
else
TRACE(ddraw, "Context created (%p)\n", odev->ctx);
/* Now override the surface's Flip method (if in double buffering) */
surface->s.d3d_device = (void *) odev;
if (surface->s.backbuffer != NULL)
surface->s.backbuffer->s.d3d_device = (void *) odev;
#endif
odev->rs.src = GL_ONE; odev->rs.src = GL_ONE;
odev->rs.dst = GL_ZERO; odev->rs.dst = GL_ZERO;
odev->rs.mag = GL_NEAREST; odev->rs.mag = GL_NEAREST;
@ -180,9 +230,14 @@ int is_OpenGL(REFCLSID rguid, IDirectDrawSurfaceImpl* surface, IDirect3DDevice2I
memcpy(odev->proj_mat , id_mat, 16 * sizeof(float)); memcpy(odev->proj_mat , id_mat, 16 * sizeof(float));
/* Initialisation */ /* Initialisation */
TRACE(ddraw, "Setting current context\n");
(*device)->set_context(*device); (*device)->set_context(*device);
TRACE(ddraw, "Current context set\n");
glClearColor(0.0, 0.0, 0.0, 0.0); glClearColor(0.0, 0.0, 0.0, 0.0);
glColor3f(1.0, 1.0, 1.0); glColor3f(1.0, 1.0, 1.0);
LEAVE_GL();
TRACE(ddraw, "OpenGL device created \n");
return 1; return 1;
} }
@ -226,6 +281,17 @@ static ULONG WINAPI IDirect3DDevice2Impl_Release(LPDIRECT3DDEVICE2 iface)
FIXME( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref ); FIXME( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
if (!--(This->ref)) { if (!--(This->ref)) {
OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) This;
#ifdef USE_OSMESA
OSMesaDestroyContext(odev->ctx);
#else
ENTER_GL();
glXDestroyContext(display,
odev->ctx);
LEAVE_GL();
#endif
HeapFree(GetProcessHeap(),0,This); HeapFree(GetProcessHeap(),0,This);
return 0; return 0;
} }
@ -473,15 +539,18 @@ static HRESULT WINAPI IDirect3DDevice2Impl_BeginScene(LPDIRECT3DDEVICE2 iface)
static HRESULT WINAPI IDirect3DDevice2Impl_EndScene(LPDIRECT3DDEVICE2 iface) static HRESULT WINAPI IDirect3DDevice2Impl_EndScene(LPDIRECT3DDEVICE2 iface)
{ {
ICOM_THIS(IDirect3DDevice2Impl,iface); ICOM_THIS(IDirect3DDevice2Impl,iface);
#ifdef USE_OSMESA
OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) This; OpenGL_IDirect3DDevice2 *odev = (OpenGL_IDirect3DDevice2 *) This;
LPDIRECTDRAWSURFACE3 surf = (LPDIRECTDRAWSURFACE3) This->surface; LPDIRECTDRAWSURFACE3 surf = (LPDIRECTDRAWSURFACE3) This->surface;
DDSURFACEDESC sdesc; DDSURFACEDESC sdesc;
int x,y; int x,y;
unsigned char *src; unsigned char *src;
unsigned short *dest; unsigned short *dest;
#endif
FIXME(ddraw, "(%p)->(): stub\n", This); FIXME(ddraw, "(%p)->(): stub\n", This);
#ifdef USE_OSMESA
/* Here we copy back the OpenGL scene to the the DDraw surface */ /* Here we copy back the OpenGL scene to the the DDraw surface */
/* First, lock the surface */ /* First, lock the surface */
IDirectDrawSurface3_Lock(surf,NULL,&sdesc,DDLOCK_WRITEONLY,0); IDirectDrawSurface3_Lock(surf,NULL,&sdesc,DDLOCK_WRITEONLY,0);
@ -512,6 +581,9 @@ static HRESULT WINAPI IDirect3DDevice2Impl_EndScene(LPDIRECT3DDEVICE2 iface)
/* Unlock the surface */ /* Unlock the surface */
IDirectDrawSurface3_Unlock(surf,sdesc.y.lpSurface); IDirectDrawSurface3_Unlock(surf,sdesc.y.lpSurface);
#else
/* No need to do anything here... */
#endif
return DD_OK; return DD_OK;
} }
@ -707,7 +779,9 @@ static HRESULT WINAPI IDirect3DDevice2Impl_SetLightState(LPDIRECT3DDEVICE2 iface
IDirect3DMaterial2Impl* mat = (IDirect3DMaterial2Impl*) dwLightState; IDirect3DMaterial2Impl* mat = (IDirect3DMaterial2Impl*) dwLightState;
if (mat != NULL) { if (mat != NULL) {
ENTER_GL();
mat->activate(mat); mat->activate(mat);
LEAVE_GL();
} else { } else {
TRACE(ddraw, "Zoups !!!\n"); TRACE(ddraw, "Zoups !!!\n");
} }
@ -720,7 +794,9 @@ static HRESULT WINAPI IDirect3DDevice2Impl_SetLightState(LPDIRECT3DDEVICE2 iface
light[1] = ((dwLightState >> 8) & 0xFF) / 255.0; light[1] = ((dwLightState >> 8) & 0xFF) / 255.0;
light[2] = ((dwLightState >> 0) & 0xFF) / 255.0; light[2] = ((dwLightState >> 0) & 0xFF) / 255.0;
light[3] = 1.0; light[3] = 1.0;
ENTER_GL();
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (float *) light); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (float *) light);
LEAVE_GL();
} break; } break;
case D3DLIGHTSTATE_COLORMODEL: /* 3 */ case D3DLIGHTSTATE_COLORMODEL: /* 3 */
@ -757,6 +833,8 @@ static HRESULT WINAPI IDirect3DDevice2Impl_SetTransform(LPDIRECT3DDEVICE2 iface,
FIXME(ddraw, "(%p)->(%d,%p): stub\n", This, d3dts, lpmatrix); FIXME(ddraw, "(%p)->(%d,%p): stub\n", This, d3dts, lpmatrix);
ENTER_GL();
/* Using a trial and failure approach, I found that the order of /* Using a trial and failure approach, I found that the order of
Direct3D transformations that works best is : Direct3D transformations that works best is :
@ -813,6 +891,8 @@ static HRESULT WINAPI IDirect3DDevice2Impl_SetTransform(LPDIRECT3DDEVICE2 iface,
break; break;
} }
LEAVE_GL();
return DD_OK; return DD_OK;
} }
@ -1014,7 +1094,9 @@ static HRESULT WINAPI IDirect3DDevice2Impl_DrawPrimitive(LPDIRECT3DDEVICE2 iface
TRACE(ddraw, "(%p)->(%d,%d,%p,%ld,%08lx): stub\n", This, d3dp, d3dv, lpvertex, vertcount, dwFlags); TRACE(ddraw, "(%p)->(%d,%d,%p,%ld,%08lx): stub\n", This, d3dp, d3dv, lpvertex, vertcount, dwFlags);
ENTER_GL();
DRAW_PRIMITIVE(vertcount, vx_index); DRAW_PRIMITIVE(vertcount, vx_index);
LEAVE_GL();
return D3D_OK; return D3D_OK;
} }
@ -1036,7 +1118,9 @@ static HRESULT WINAPI IDirect3DDevice2Impl_DrawIndexedPrimitive(LPDIRECT3DDEVICE
TRACE(ddraw, "(%p)->(%d,%d,%p,%ld,%p,%ld,%08lx): stub\n", This, d3dp, d3dv, lpvertex, vertcount, lpindexes, indexcount, dwFlags); TRACE(ddraw, "(%p)->(%d,%d,%p,%ld,%p,%ld,%08lx): stub\n", This, d3dp, d3dv, lpvertex, vertcount, lpindexes, indexcount, dwFlags);
ENTER_GL();
DRAW_PRIMITIVE(indexcount, lpindexes[vx_index]); DRAW_PRIMITIVE(indexcount, lpindexes[vx_index]);
LEAVE_GL();
return D3D_OK; return D3D_OK;
} }
@ -1141,6 +1225,10 @@ int is_OpenGL_dx3(REFCLSID rguid, IDirectDrawSurfaceImpl* surface, IDirect3DDevi
{ {
if (!memcmp(&IID_D3DDEVICE_OpenGL,rguid,sizeof(IID_D3DDEVICE_OpenGL))) { if (!memcmp(&IID_D3DDEVICE_OpenGL,rguid,sizeof(IID_D3DDEVICE_OpenGL))) {
OpenGL_IDirect3DDevice *odev; OpenGL_IDirect3DDevice *odev;
#ifndef USE_OSMESA
int attributeList[]={ GLX_RGBA, GLX_DEPTH_SIZE, 16, GLX_DOUBLEBUFFER, None };
XVisualInfo *xvis;
#endif
*device = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(OpenGL_IDirect3DDevice)); *device = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(OpenGL_IDirect3DDevice));
odev = (OpenGL_IDirect3DDevice *) (*device); odev = (OpenGL_IDirect3DDevice *) (*device);
@ -1157,9 +1245,35 @@ int is_OpenGL_dx3(REFCLSID rguid, IDirectDrawSurfaceImpl* surface, IDirect3DDevi
TRACE(ddraw, "OpenGL device created \n"); TRACE(ddraw, "OpenGL device created \n");
/* Create the OpenGL context */ /* Create the OpenGL context */
#ifdef USE_OSMESA
odev->ctx = OSMesaCreateContext(OSMESA_RGBA, NULL); odev->ctx = OSMesaCreateContext(OSMESA_RGBA, NULL);
odev->buffer = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, odev->buffer = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
surface->s.surface_desc.dwWidth * surface->s.surface_desc.dwHeight * 4); surface->s.surface_desc.dwWidth * surface->s.surface_desc.dwHeight * 4);
#else
/* First get the correct visual */
TRACE(ddraw, "Backbuffer : %d\n", surface->s.backbuffer == NULL);
/* if (surface->s.backbuffer == NULL)
attributeList[3] = None; */
ENTER_GL();
xvis = glXChooseVisual(display,
DefaultScreen(display),
attributeList);
if (xvis == NULL)
ERR(ddraw, "No visual found !\n");
else
TRACE(ddraw, "Visual found\n");
/* Create the context */
odev->ctx = glXCreateContext(display,
xvis,
NULL,
GL_TRUE);
TRACE(ddraw, "Context created\n");
/* Now override the surface's Flip method (if in double buffering) */
surface->s.d3d_device = (void *) odev;
if (surface->s.backbuffer != NULL)
surface->s.backbuffer->s.d3d_device = (void *) odev;
#endif
odev->rs.src = GL_ONE; odev->rs.src = GL_ONE;
odev->rs.dst = GL_ZERO; odev->rs.dst = GL_ZERO;
odev->rs.mag = GL_NEAREST; odev->rs.mag = GL_NEAREST;
@ -1216,6 +1330,17 @@ static ULONG WINAPI IDirect3DDeviceImpl_Release(LPDIRECT3DDEVICE iface)
FIXME( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref ); FIXME( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
if (!--(This->ref)) { if (!--(This->ref)) {
OpenGL_IDirect3DDevice *odev = (OpenGL_IDirect3DDevice *) This;
#ifdef USE_OSMESA
OSMesaDestroyContext(odev->ctx);
#else
ENTER_GL();
glXDestroyContext(display,
odev->ctx);
LEAVE_GL();
#endif
HeapFree(GetProcessHeap(),0,This); HeapFree(GetProcessHeap(),0,This);
return 0; return 0;
} }
@ -1484,15 +1609,18 @@ static HRESULT WINAPI IDirect3DDeviceImpl_BeginScene(LPDIRECT3DDEVICE iface)
static HRESULT WINAPI IDirect3DDeviceImpl_EndScene(LPDIRECT3DDEVICE iface) static HRESULT WINAPI IDirect3DDeviceImpl_EndScene(LPDIRECT3DDEVICE iface)
{ {
ICOM_THIS(IDirect3DDeviceImpl,iface); ICOM_THIS(IDirect3DDeviceImpl,iface);
#ifdef USE_OSMESA
OpenGL_IDirect3DDevice *odev = (OpenGL_IDirect3DDevice *) This; OpenGL_IDirect3DDevice *odev = (OpenGL_IDirect3DDevice *) This;
LPDIRECTDRAWSURFACE3 surf = (LPDIRECTDRAWSURFACE3) This->surface; LPDIRECTDRAWSURFACE3 surf = (LPDIRECTDRAWSURFACE3) This->surface;
DDSURFACEDESC sdesc; DDSURFACEDESC sdesc;
int x,y; int x,y;
unsigned char *src; unsigned char *src;
unsigned short *dest; unsigned short *dest;
#endif
FIXME(ddraw, "(%p)->(): stub\n", This); FIXME(ddraw, "(%p)->(): stub\n", This);
#ifdef USE_OSMESA
/* Here we copy back the OpenGL scene to the the DDraw surface */ /* Here we copy back the OpenGL scene to the the DDraw surface */
/* First, lock the surface */ /* First, lock the surface */
IDirectDrawSurface3_Lock(surf,NULL,&sdesc,DDLOCK_WRITEONLY,0); IDirectDrawSurface3_Lock(surf,NULL,&sdesc,DDLOCK_WRITEONLY,0);
@ -1524,6 +1652,9 @@ static HRESULT WINAPI IDirect3DDeviceImpl_EndScene(LPDIRECT3DDEVICE iface)
/* Unlock the surface */ /* Unlock the surface */
IDirectDrawSurface3_Unlock(surf,sdesc.y.lpSurface); IDirectDrawSurface3_Unlock(surf,sdesc.y.lpSurface);
#else
/* No need to do anything here... */
#endif
return DD_OK; return DD_OK;
} }

View File

@ -186,6 +186,8 @@ static void execute(LPDIRECT3DEXECUTEBUFFER lpBuff,
if (TRACE_ON(ddraw)) if (TRACE_ON(ddraw))
_dump_executedata(&(ilpBuff->data)); _dump_executedata(&(ilpBuff->data));
ENTER_GL();
while (1) { while (1) {
LPD3DINSTRUCTION current = (LPD3DINSTRUCTION) instr; LPD3DINSTRUCTION current = (LPD3DINSTRUCTION) instr;
BYTE size; BYTE size;
@ -657,6 +659,7 @@ static void execute(LPDIRECT3DEXECUTEBUFFER lpBuff,
} }
end_of_buffer: end_of_buffer:
LEAVE_GL();
} }
/******************************************************************************* /*******************************************************************************

View File

@ -81,6 +81,7 @@ static void update(IDirect3DLightImpl* This) {
} }
static void activate(IDirect3DLightImpl* This) { static void activate(IDirect3DLightImpl* This) {
ENTER_GL();
update(This); update(This);
/* If was not active, activate it */ /* If was not active, activate it */
@ -89,6 +90,7 @@ static void activate(IDirect3DLightImpl* This) {
This->is_active = 1; This->is_active = 1;
} }
LEAVE_GL();
return ; return ;
} }
@ -220,8 +222,10 @@ static HRESULT WINAPI IDirect3DLightImpl_SetLight(LPDIRECT3DLIGHT iface,
break; break;
} }
ENTER_GL();
if (This->is_active) if (This->is_active)
update(This); update(This);
LEAVE_GL();
return DD_OK; return DD_OK;
} }

View File

@ -27,6 +27,7 @@ static ICOM_VTABLE(IDirect3DMaterial) material_vtable;
static void activate(IDirect3DMaterial2Impl* This) { static void activate(IDirect3DMaterial2Impl* This) {
TRACE(ddraw, "Activating material %p\n", This); TRACE(ddraw, "Activating material %p\n", This);
ENTER_GL();
/* First, set the rendering context */ /* First, set the rendering context */
if (This->use_d3d2) if (This->use_d3d2)
This->device.active_device2->set_context(This->device.active_device2); This->device.active_device2->set_context(This->device.active_device2);
@ -55,6 +56,7 @@ static void activate(IDirect3DMaterial2Impl* This) {
TRACE(ddraw, "Power : %f\n", This->mat.e.power); TRACE(ddraw, "Power : %f\n", This->mat.e.power);
TRACE(ddraw, "Texture handle : %08lx\n", (DWORD)This->mat.hTexture); TRACE(ddraw, "Texture handle : %08lx\n", (DWORD)This->mat.hTexture);
LEAVE_GL();
return ; return ;
} }

View File

@ -142,11 +142,13 @@ HRESULT WINAPI SetColorKey_cb(IDirect3DTexture2Impl *texture, DWORD dwFlags, LP
tex_d->ddpfPixelFormat.x.dwRGBBitCount / 8 /* RGB bits for each colors */ ); tex_d->ddpfPixelFormat.x.dwRGBBitCount / 8 /* RGB bits for each colors */ );
/* Now, save the current texture */ /* Now, save the current texture */
ENTER_GL();
glGetIntegerv(GL_TEXTURE_BINDING_2D, &current_texture); glGetIntegerv(GL_TEXTURE_BINDING_2D, &current_texture);
/* If the GetHandle was not done yet, it's an error */ /* If the GetHandle was not done yet, it's an error */
if (texture->tex_name == 0) { if (texture->tex_name == 0) {
ERR(ddraw, "Unloaded texture !\n"); ERR(ddraw, "Unloaded texture !\n");
LEAVE_GL();
return DD_OK; return DD_OK;
} }
glBindTexture(GL_TEXTURE_2D, texture->tex_name); glBindTexture(GL_TEXTURE_2D, texture->tex_name);
@ -206,6 +208,7 @@ HRESULT WINAPI SetColorKey_cb(IDirect3DTexture2Impl *texture, DWORD dwFlags, LP
} else { } else {
ERR(ddraw, "Unhandled texture format (neither RGB nor INDEX)\n"); ERR(ddraw, "Unhandled texture format (neither RGB nor INDEX)\n");
} }
LEAVE_GL();
return DD_OK; return DD_OK;
} }
@ -246,7 +249,9 @@ static ULONG WINAPI IDirect3DTexture2Impl_Release(LPDIRECT3DTEXTURE2 iface)
if (!--(This->ref)) { if (!--(This->ref)) {
/* Delete texture from OpenGL */ /* Delete texture from OpenGL */
ENTER_GL();
glDeleteTextures(1, &(This->tex_name)); glDeleteTextures(1, &(This->tex_name));
LEAVE_GL();
/* Release surface */ /* Release surface */
IDirectDrawSurface4_Release((IDirectDrawSurface4*)This->surface); IDirectDrawSurface4_Release((IDirectDrawSurface4*)This->surface);
@ -270,10 +275,12 @@ static HRESULT WINAPI IDirect3DTextureImpl_GetHandle(LPDIRECT3DTEXTURE iface,
*lpHandle = (D3DTEXTUREHANDLE) This; *lpHandle = (D3DTEXTUREHANDLE) This;
/* Now, bind a new texture */ /* Now, bind a new texture */
ENTER_GL();
ilpD3DDevice->set_context(ilpD3DDevice); ilpD3DDevice->set_context(ilpD3DDevice);
This->D3Ddevice = (void *) ilpD3DDevice; This->D3Ddevice = (void *) ilpD3DDevice;
if (This->tex_name == 0) if (This->tex_name == 0)
glGenTextures(1, &(This->tex_name)); glGenTextures(1, &(This->tex_name));
LEAVE_GL();
TRACE(ddraw, "OpenGL texture handle is : %d\n", This->tex_name); TRACE(ddraw, "OpenGL texture handle is : %d\n", This->tex_name);
@ -311,10 +318,12 @@ static HRESULT WINAPI IDirect3DTexture2Impl_GetHandle(LPDIRECT3DTEXTURE2 iface,
*lpHandle = (D3DTEXTUREHANDLE) This; *lpHandle = (D3DTEXTUREHANDLE) This;
/* Now, bind a new texture */ /* Now, bind a new texture */
ENTER_GL();
ilpD3DDevice2->set_context(ilpD3DDevice2); ilpD3DDevice2->set_context(ilpD3DDevice2);
This->D3Ddevice = (void *) ilpD3DDevice2; This->D3Ddevice = (void *) ilpD3DDevice2;
if (This->tex_name == 0) if (This->tex_name == 0)
glGenTextures(1, &(This->tex_name)); glGenTextures(1, &(This->tex_name));
LEAVE_GL();
TRACE(ddraw, "OpenGL texture handle is : %d\n", This->tex_name); TRACE(ddraw, "OpenGL texture handle is : %d\n", This->tex_name);
@ -371,6 +380,8 @@ static HRESULT WINAPI IDirect3DTexture2Impl_Load(LPDIRECT3DTEXTURE2 iface,
texture object. */ texture object. */
memcpy(dst_d->y.lpSurface, src_d->y.lpSurface, src_d->dwWidth * src_d->dwHeight * bpp); memcpy(dst_d->y.lpSurface, src_d->y.lpSurface, src_d->dwWidth * src_d->dwHeight * bpp);
ENTER_GL();
/* Now, load the texture */ /* Now, load the texture */
/* d3dd->set_context(d3dd); We need to set the context somehow.... */ /* d3dd->set_context(d3dd); We need to set the context somehow.... */
glGetIntegerv(GL_TEXTURE_BINDING_2D, &current_texture); glGetIntegerv(GL_TEXTURE_BINDING_2D, &current_texture);
@ -390,6 +401,7 @@ static HRESULT WINAPI IDirect3DTexture2Impl_Load(LPDIRECT3DTEXTURE2 iface,
if (pal == NULL) { if (pal == NULL) {
ERR(ddraw, "Palettized texture Loading with a NULL palette !\n"); ERR(ddraw, "Palettized texture Loading with a NULL palette !\n");
LEAVE_GL();
return D3DERR_TEXTURE_LOAD_FAILED; return D3DERR_TEXTURE_LOAD_FAILED;
} }
@ -505,6 +517,8 @@ static HRESULT WINAPI IDirect3DTexture2Impl_Load(LPDIRECT3DTEXTURE2 iface,
} }
glBindTexture(GL_TEXTURE_2D, current_texture); glBindTexture(GL_TEXTURE_2D, current_texture);
LEAVE_GL();
} }
return D3D_OK; return D3D_OK;

View File

@ -11,12 +11,12 @@
#include "ddraw.h" #include "ddraw.h"
#include "d3d.h" #include "d3d.h"
#include "debug.h" #include "debug.h"
#include "x11drv.h"
#include "d3d_private.h" #include "d3d_private.h"
DEFAULT_DEBUG_CHANNEL(ddraw) DEFAULT_DEBUG_CHANNEL(ddraw)
#ifdef HAVE_MESAGL #ifdef HAVE_MESAGL
static ICOM_VTABLE(IDirect3DViewport2) viewport2_vtable; static ICOM_VTABLE(IDirect3DViewport2) viewport2_vtable;
@ -249,10 +249,12 @@ static HRESULT WINAPI IDirect3DViewport2Impl_Clear(LPDIRECT3DVIEWPORT2 iface,
} }
/* Clears the screen */ /* Clears the screen */
ENTER_GL();
glGetBooleanv(GL_DEPTH_TEST, &ztest); glGetBooleanv(GL_DEPTH_TEST, &ztest);
glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */ glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDepthMask(ztest); glDepthMask(ztest);
LEAVE_GL();
return DD_OK; return DD_OK;
} }

View File

@ -554,9 +554,9 @@ static HRESULT WINAPI IDirectDrawSurface4Impl_Lock(
FIXME(ddraw," lprect: %dx%d-%dx%d\n", FIXME(ddraw," lprect: %dx%d-%dx%d\n",
lprect->top,lprect->left,lprect->bottom,lprect->right lprect->top,lprect->left,lprect->bottom,lprect->right
); );
lpddsd->y.lpSurface = (char *) This->s.surface_desc.y.lpSurface + lpddsd->y.lpSurface = (LPVOID) ((char *) This->s.surface_desc.y.lpSurface +
(lprect->top*This->s.surface_desc.lPitch) + (lprect->top*This->s.surface_desc.lPitch) +
(lprect->left*(This->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8)); (lprect->left*(This->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8)));
} else { } else {
assert(This->s.surface_desc.y.lpSurface); assert(This->s.surface_desc.y.lpSurface);
} }
@ -666,6 +666,20 @@ static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Flip(
ICOM_THIS(IDirectDrawSurface4Impl,iface); ICOM_THIS(IDirectDrawSurface4Impl,iface);
IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto; IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags); TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
#ifdef HAVE_MESAGL
if ((This->s.d3d_device != NULL) ||
((This->s.backbuffer != NULL) && (This->s.backbuffer->s.d3d_device != NULL))) {
TRACE(ddraw," - OpenGL flip\n");
ENTER_GL();
glXSwapBuffers(display,
This->s.ddraw->d.drawable);
LEAVE_GL();
return DD_OK;
}
#endif /* defined(HAVE_MESAGL) */
if (!This->s.ddraw->d.paintable) if (!This->s.ddraw->d.paintable)
return DD_OK; return DD_OK;
@ -2933,6 +2947,12 @@ static HRESULT WINAPI IDirectDraw2Impl_SetCooperativeLevel(
WND *tmpWnd = WIN_FindWndPtr(hwnd); WND *tmpWnd = WIN_FindWndPtr(hwnd);
This->d.drawable = X11DRV_WND_GetXWindow(tmpWnd); This->d.drawable = X11DRV_WND_GetXWindow(tmpWnd);
WIN_ReleaseWndPtr(tmpWnd); WIN_ReleaseWndPtr(tmpWnd);
if( !This->d.drawable ) {
This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
WIN_ReleaseDesktop();
}
TRACE(ddraw, "Setting drawable to %ld\n", This->d.drawable);
} }
return DD_OK; return DD_OK;
@ -3330,14 +3350,16 @@ static HRESULT WINAPI Xlib_IDirectDrawImpl_SetDisplayMode(
tmpWnd = WIN_FindWndPtr(This->d.window); tmpWnd = WIN_FindWndPtr(This->d.window);
This->d.paintable = 1; This->d.paintable = 1;
This->d.drawable = ((X11DRV_WND_DATA *) tmpWnd->pDriverData)->window; This->d.drawable = ((X11DRV_WND_DATA *) tmpWnd->pDriverData)->window;
/* We don't have a context for this window. Host off the desktop */ WIN_ReleaseWndPtr(tmpWnd);
/* We don't have a context for this window. Host off the desktop */
if( !This->d.drawable ) if( !This->d.drawable )
{ {
This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window; This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
WIN_ReleaseDesktop(); WIN_ReleaseDesktop();
} }
WIN_ReleaseWndPtr(tmpWnd); TRACE(ddraw, "Setting drawable to %ld\n", This->d.drawable);
return DD_OK; return DD_OK;
} }

View File

@ -148,6 +148,9 @@ struct _common_directdrawsurface
/* Callback for loaded textures */ /* Callback for loaded textures */
IDirect3DTexture2Impl* texture; IDirect3DTexture2Impl* texture;
HRESULT WINAPI (*SetColorKey_cb)(IDirect3DTexture2Impl *texture, DWORD dwFlags, LPDDCOLORKEY ckey ) ; HRESULT WINAPI (*SetColorKey_cb)(IDirect3DTexture2Impl *texture, DWORD dwFlags, LPDDCOLORKEY ckey ) ;
/* Storage for attached device (void * as it can be either a Device or a Device2) */
void *d3d_device;
}; };
struct _dga_directdrawsurface struct _dga_directdrawsurface

View File

@ -21,6 +21,7 @@
/* These will need to have some #ifdef / #endif added to support /* These will need to have some #ifdef / #endif added to support
more than the X11 using OSMesa target */ more than the X11 using OSMesa target */
#include <GL/osmesa.h> #include <GL/osmesa.h>
#include <GL/glx.h>
#undef APIENTRY #undef APIENTRY
#undef CALLBACK #undef CALLBACK