- add ZBuffer write support

- some TRACEing fixes
This commit is contained in:
Lionel Ulmer 2003-09-15 20:00:03 +00:00 committed by Alexandre Julliard
parent 6288266a61
commit 8c1c276b5b
8 changed files with 143 additions and 16 deletions

View File

@ -204,7 +204,8 @@ struct IDirect3DDeviceImpl
D3DVIEWPORT7 active_viewport; D3DVIEWPORT7 active_viewport;
IDirectDrawSurfaceImpl *current_texture[MAX_TEXTURES]; IDirectDrawSurfaceImpl *current_texture[MAX_TEXTURES];
IDirectDrawSurfaceImpl *current_zbuffer;
/* Current transformation matrices */ /* Current transformation matrices */
D3DMATRIX *world_mat; D3DMATRIX *world_mat;
D3DMATRIX *view_mat; D3DMATRIX *view_mat;

View File

@ -1096,6 +1096,54 @@ GL_IDirect3DDeviceImpl_1_CreateExecuteBuffer(LPDIRECT3DDEVICE iface,
return ret_value; return ret_value;
} }
static void flush_zbuffer_to_GL(IDirect3DDeviceImpl *d3d_dev, LPCRECT pRect, IDirectDrawSurfaceImpl *surf) {
static BOOLEAN first = TRUE;
IDirect3DDeviceGLImpl* gl_d3d_dev = (IDirect3DDeviceGLImpl*) d3d_dev;
int row;
GLenum type;
if (first == TRUE) {
MESSAGE("Warning : application does direct locking of ZBuffer - expect slowdowns on many GL implementations :-)\n");
first = FALSE;
}
TRACE("flushing ZBuffer back to GL\n");
if (gl_d3d_dev->transform_state != GL_TRANSFORM_ORTHO) {
gl_d3d_dev->transform_state = GL_TRANSFORM_ORTHO;
d3ddevice_set_ortho(d3d_dev);
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
if (gl_d3d_dev->depth_test == 0) glEnable(GL_DEPTH_TEST);
if (d3d_dev->state_block.render_state[D3DRENDERSTATE_ZFUNC - 1] != D3DCMP_ALWAYS) glDepthFunc(GL_ALWAYS);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
/* This loop here is to prevent using PixelZoom that may be unoptimized for the 1.0 / -1.0 case
in some drivers...
*/
switch (surf->surface_desc.u4.ddpfPixelFormat.u1.dwZBufferBitDepth) {
case 16: type = GL_UNSIGNED_SHORT; break;
case 32: type = GL_UNSIGNED_INT; break;
default: FIXME("Unhandled ZBuffer format !\n"); goto restore_state;
}
for (row = 0; row < surf->surface_desc.dwHeight; row++) {
/* glRasterPos3d(0.0, row + 1.0, 0.5); */
glRasterPos2i(0, row + 1);
glDrawPixels(surf->surface_desc.dwWidth, 1, GL_DEPTH_COMPONENT, type,
((unsigned char *) surf->surface_desc.lpSurface) + (row * surf->surface_desc.u1.lPitch));
}
restore_state:
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
if (d3d_dev->state_block.render_state[D3DRENDERSTATE_ZFUNC - 1] != D3DCMP_ALWAYS)
glDepthFunc(convert_D3D_compare_to_GL(d3d_dev->state_block.render_state[D3DRENDERSTATE_ZFUNC - 1]));
if (gl_d3d_dev->depth_test == 0) glDisable(GL_DEPTH_TEST);
}
/* These are the various handler used in the generic path */ /* These are the various handler used in the generic path */
inline static void handle_xyz(D3DVALUE *coords) { inline static void handle_xyz(D3DVALUE *coords) {
glVertex3fv(coords); glVertex3fv(coords);
@ -1251,8 +1299,26 @@ static void draw_primitive_strided(IDirect3DDeviceImpl *This,
if (glThis->state[WINE_GL_BUFFER_BACK] == SURFACE_MEMORY_DIRTY) { if (glThis->state[WINE_GL_BUFFER_BACK] == SURFACE_MEMORY_DIRTY) {
This->flush_to_framebuffer(This, &(glThis->lock_rect[WINE_GL_BUFFER_BACK]), glThis->lock_surf[WINE_GL_BUFFER_BACK]); This->flush_to_framebuffer(This, &(glThis->lock_rect[WINE_GL_BUFFER_BACK]), glThis->lock_surf[WINE_GL_BUFFER_BACK]);
} }
glThis->state[WINE_GL_BUFFER_BACK] = SURFACE_GL; glThis->state[WINE_GL_BUFFER_BACK] = SURFACE_GL;
if (This->current_zbuffer == NULL) {
/* Search for an attached ZBuffer */
static const DDSCAPS2 zbuf_caps = { DDSCAPS_ZBUFFER, 0, 0, 0 };
LPDIRECTDRAWSURFACE7 zbuf;
HRESULT hr;
hr = IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(This->surface, IDirectDrawSurface7),
(DDSCAPS2 *) &zbuf_caps, &zbuf);
if (!FAILED(hr)) {
This->current_zbuffer = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, zbuf);
IDirectDrawSurface7_Release(zbuf);
}
}
if (This->current_zbuffer != NULL) {
if (This->current_zbuffer->get_dirty_status(This->current_zbuffer, NULL)) {
flush_zbuffer_to_GL(This, NULL, This->current_zbuffer);
}
}
/* Just a hack for now.. Will have to find better algorithm :-/ */ /* Just a hack for now.. Will have to find better algorithm :-/ */
if ((d3dvtVertexType & D3DFVF_POSITION_MASK) != D3DFVF_XYZ) { if ((d3dvtVertexType & D3DFVF_POSITION_MASK) != D3DFVF_XYZ) {
@ -1270,7 +1336,6 @@ static void draw_primitive_strided(IDirect3DDeviceImpl *This,
glThis->current_active_tex_unit = GL_TEXTURE0_WINE; glThis->current_active_tex_unit = GL_TEXTURE0_WINE;
} }
draw_primitive_handle_GL_state(This, draw_primitive_handle_GL_state(This,
(d3dvtVertexType & D3DFVF_POSITION_MASK) != D3DFVF_XYZ, (d3dvtVertexType & D3DFVF_POSITION_MASK) != D3DFVF_XYZ,
vertex_lighted); vertex_lighted);
@ -3160,11 +3225,11 @@ d3ddevice_set_ortho(IDirect3DDeviceImpl *This)
to OpenGL screen coordinates (ie the upper left corner is not the same). to OpenGL screen coordinates (ie the upper left corner is not the same).
For Z, the mystery is what should it be mapped to ? Ie should the resulting range be between For Z, the mystery is what should it be mapped to ? Ie should the resulting range be between
-1.0 and 1.0 (as the X and Y coordinates) or between 0.0 and 1.0 ? */ -1.0 and 1.0 (as the X and Y coordinates) or between 0.0 and 1.0 ? */
trans_mat[ 0] = 2.0 / width; trans_mat[ 4] = 0.0; trans_mat[ 8] = 0.0; trans_mat[12] = -1.0; trans_mat[ 0] = 2.0 / width; trans_mat[ 4] = 0.0; trans_mat[ 8] = 0.0; trans_mat[12] = -1.0;
trans_mat[ 1] = 0.0; trans_mat[ 5] = -2.0 / height; trans_mat[ 9] = 0.0; trans_mat[13] = 1.0; trans_mat[ 1] = 0.0; trans_mat[ 5] = -2.0 / height; trans_mat[ 9] = 0.0; trans_mat[13] = 1.0;
trans_mat[ 2] = 0.0; trans_mat[ 6] = 0.0; trans_mat[10] = 1.0; trans_mat[14] = -1.0; trans_mat[ 2] = 0.0; trans_mat[ 6] = 0.0; trans_mat[10] = 2.0; trans_mat[14] = -1.0;
trans_mat[ 3] = 0.0; trans_mat[ 7] = 0.0; trans_mat[11] = 0.0; trans_mat[15] = 1.0; trans_mat[ 3] = 0.0; trans_mat[ 7] = 0.0; trans_mat[11] = 0.0; trans_mat[15] = 1.0;
ENTER_GL(); ENTER_GL();
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); glLoadIdentity();
@ -3874,6 +3939,7 @@ static void fill_opengl_primcaps(D3DPRIMCAPS *pc)
static void fill_caps(void) static void fill_caps(void)
{ {
GLint max_clip_planes; GLint max_clip_planes;
GLint depth_bits;
/* Fill first all the fields with default values which will be overriden later on with /* Fill first all the fields with default values which will be overriden later on with
correct ones from the GL code correct ones from the GL code
@ -3886,7 +3952,6 @@ static void fill_caps(void)
fill_opengl_primcaps(&(opengl_device_caps.dpcLineCaps)); fill_opengl_primcaps(&(opengl_device_caps.dpcLineCaps));
fill_opengl_primcaps(&(opengl_device_caps.dpcTriCaps)); fill_opengl_primcaps(&(opengl_device_caps.dpcTriCaps));
opengl_device_caps.dwDeviceRenderBitDepth = DDBD_16|DDBD_24|DDBD_32; opengl_device_caps.dwDeviceRenderBitDepth = DDBD_16|DDBD_24|DDBD_32;
opengl_device_caps.dwDeviceZBufferBitDepth = DDBD_16|DDBD_24|DDBD_32;
opengl_device_caps.dwMinTextureWidth = 1; opengl_device_caps.dwMinTextureWidth = 1;
opengl_device_caps.dwMinTextureHeight = 1; opengl_device_caps.dwMinTextureHeight = 1;
opengl_device_caps.dwMaxTextureWidth = 1024; opengl_device_caps.dwMaxTextureWidth = 1024;
@ -3937,6 +4002,15 @@ static void fill_caps(void)
glGetIntegerv(GL_MAX_CLIP_PLANES, &max_clip_planes); glGetIntegerv(GL_MAX_CLIP_PLANES, &max_clip_planes);
opengl_device_caps.wMaxUserClipPlanes = max_clip_planes; opengl_device_caps.wMaxUserClipPlanes = max_clip_planes;
TRACE(": max clipping planes = %d\n", opengl_device_caps.wMaxUserClipPlanes); TRACE(": max clipping planes = %d\n", opengl_device_caps.wMaxUserClipPlanes);
glGetIntegerv(GL_DEPTH_BITS, &depth_bits);
TRACE(": Z bits = %d\n", depth_bits);
switch (depth_bits) {
case 16: opengl_device_caps.dwDeviceZBufferBitDepth = DDBD_16; break;
case 24: opengl_device_caps.dwDeviceZBufferBitDepth = DDBD_24; break;
case 32: opengl_device_caps.dwDeviceZBufferBitDepth = DDBD_32; break;
default: opengl_device_caps.dwDeviceZBufferBitDepth = DDBD_16|DDBD_24|DDBD_32; break;
}
} }
BOOL BOOL

View File

@ -322,6 +322,7 @@ struct IDirectDrawSurfaceImpl
LPVOID tex_private; LPVOID tex_private;
void (*lock_update_prev)(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags); void (*lock_update_prev)(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags);
void (*unlock_update_prev)(IDirectDrawSurfaceImpl* This, LPCRECT pRect); void (*unlock_update_prev)(IDirectDrawSurfaceImpl* This, LPCRECT pRect);
BOOLEAN (*get_dirty_status)(IDirectDrawSurfaceImpl* This, LPCRECT pRect);
}; };
/***************************************************************************** /*****************************************************************************

View File

@ -48,12 +48,34 @@ WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
static ICOM_VTABLE(IDirectDrawSurface7) FakeZBuffer_IDirectDrawSurface7_VTable; static ICOM_VTABLE(IDirectDrawSurface7) FakeZBuffer_IDirectDrawSurface7_VTable;
#ifdef HAVE_OPENGL
static void zbuffer_lock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags)
{
/* Note that this does not do anything for now... At least it's not needed for Grim Fandango :-) */
}
static void zbuffer_unlock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect)
{
((FakeZBuffer_DirectDrawSurfaceImpl *) This->private)->in_memory = TRUE;
}
static BOOLEAN zbuffer_get_dirty_status(IDirectDrawSurfaceImpl* This, LPCRECT pRect)
{
if (((FakeZBuffer_DirectDrawSurfaceImpl *) This->private)->in_memory == TRUE) {
((FakeZBuffer_DirectDrawSurfaceImpl *) This->private)->in_memory = FALSE;
return TRUE;
}
return FALSE;
}
#endif
HRESULT FakeZBuffer_DirectDrawSurface_Construct(IDirectDrawSurfaceImpl *This, HRESULT FakeZBuffer_DirectDrawSurface_Construct(IDirectDrawSurfaceImpl *This,
IDirectDrawImpl *pDD, IDirectDrawImpl *pDD,
const DDSURFACEDESC2 *pDDSD) const DDSURFACEDESC2 *pDDSD)
{ {
HRESULT hr; HRESULT hr;
BYTE zdepth = 16; /* Default value.. Should use the one from GL */
assert(pDDSD->ddsCaps.dwCaps & DDSCAPS_ZBUFFER); assert(pDDSD->ddsCaps.dwCaps & DDSCAPS_ZBUFFER);
hr = Main_DirectDrawSurface_Construct(This, pDD, pDDSD); hr = Main_DirectDrawSurface_Construct(This, pDD, pDDSD);
@ -65,6 +87,33 @@ HRESULT FakeZBuffer_DirectDrawSurface_Construct(IDirectDrawSurfaceImpl *This,
This->final_release = FakeZBuffer_DirectDrawSurface_final_release; This->final_release = FakeZBuffer_DirectDrawSurface_final_release;
This->duplicate_surface = FakeZBuffer_DirectDrawSurface_duplicate_surface; This->duplicate_surface = FakeZBuffer_DirectDrawSurface_duplicate_surface;
#ifdef HAVE_OPENGL
if (opengl_initialized) {
This->lock_update = zbuffer_lock_update;
This->unlock_update = zbuffer_unlock_update;
This->get_dirty_status = zbuffer_get_dirty_status;
}
#endif
/* Beginning of some D3D hacks :-) */
if (This->surface_desc.dwFlags & DDSD_ZBUFFERBITDEPTH) {
zdepth = This->surface_desc.u2.dwMipMapCount; /* This is where the Z buffer depth is stored in 'old' versions */
}
if ((This->surface_desc.dwFlags & DDSD_PIXELFORMAT) == 0) {
This->surface_desc.dwFlags |= DDSD_PIXELFORMAT;
This->surface_desc.u4.ddpfPixelFormat.dwSize = sizeof(This->surface_desc.u4.ddpfPixelFormat);
This->surface_desc.u4.ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
This->surface_desc.u4.ddpfPixelFormat.u1.dwZBufferBitDepth = zdepth;
}
if ((This->surface_desc.dwFlags & DDSD_PITCH) == 0) {
This->surface_desc.dwFlags |= DDSD_PITCH;
This->surface_desc.u1.lPitch = ((zdepth + 7) / 8) * This->surface_desc.dwWidth;
}
This->surface_desc.lpSurface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
This->surface_desc.u1.lPitch * This->surface_desc.dwHeight);
return DD_OK; return DD_OK;
} }

View File

@ -19,14 +19,9 @@
#ifndef DDRAW_DSURFACE_FAKEZBUFFER_H_INCLUDED #ifndef DDRAW_DSURFACE_FAKEZBUFFER_H_INCLUDED
#define DDRAW_DSURFACE_FAKEZBUFFER_H_INCLUDED #define DDRAW_DSURFACE_FAKEZBUFFER_H_INCLUDED
struct FakeZBuffer_DirectDrawSurfaceImpl_Part
{
int dummy;
};
typedef struct typedef struct
{ {
struct FakeZBuffer_DirectDrawSurfaceImpl_Part fakezbuffer; BOOLEAN in_memory;
} FakeZBuffer_DirectDrawSurfaceImpl; } FakeZBuffer_DirectDrawSurfaceImpl;
HRESULT HRESULT

View File

@ -38,6 +38,7 @@ GL_API_FUNCTION(glClipPlane)
GL_API_FUNCTION(glColor3f) GL_API_FUNCTION(glColor3f)
GL_API_FUNCTION(glColor3ub) GL_API_FUNCTION(glColor3ub)
GL_API_FUNCTION(glColor4ub) GL_API_FUNCTION(glColor4ub)
GL_API_FUNCTION(glColorMask)
GL_API_FUNCTION(glColorMaterial) GL_API_FUNCTION(glColorMaterial)
GL_API_FUNCTION(glCopyPixels) GL_API_FUNCTION(glCopyPixels)
GL_API_FUNCTION(glCopyTexSubImage2D) GL_API_FUNCTION(glCopyTexSubImage2D)
@ -76,11 +77,13 @@ GL_API_FUNCTION(glMatrixMode)
GL_API_FUNCTION(glMultMatrixf) GL_API_FUNCTION(glMultMatrixf)
GL_API_FUNCTION(glNormal3f) GL_API_FUNCTION(glNormal3f)
GL_API_FUNCTION(glNormal3fv) GL_API_FUNCTION(glNormal3fv)
GL_API_FUNCTION(glOrtho)
GL_API_FUNCTION(glPixelStorei) GL_API_FUNCTION(glPixelStorei)
GL_API_FUNCTION(glPolygonMode) GL_API_FUNCTION(glPolygonMode)
GL_API_FUNCTION(glPolygonOffset) GL_API_FUNCTION(glPolygonOffset)
GL_API_FUNCTION(glPopMatrix) GL_API_FUNCTION(glPopMatrix)
GL_API_FUNCTION(glPushMatrix) GL_API_FUNCTION(glPushMatrix)
GL_API_FUNCTION(glRasterPos2i)
GL_API_FUNCTION(glRasterPos3d) GL_API_FUNCTION(glRasterPos3d)
GL_API_FUNCTION(glReadBuffer) GL_API_FUNCTION(glReadBuffer)
GL_API_FUNCTION(glReadPixels) GL_API_FUNCTION(glReadPixels)

View File

@ -81,6 +81,7 @@
#define glColor3f pglColor3f #define glColor3f pglColor3f
#define glColor3ub pglColor3ub #define glColor3ub pglColor3ub
#define glColor4ub pglColor4ub #define glColor4ub pglColor4ub
#define glColorMask pglColorMask
#define glCopyPixels pglCopyPixels #define glCopyPixels pglCopyPixels
#define glCopyTexSubImage2D pglCopyTexSubImage2D #define glCopyTexSubImage2D pglCopyTexSubImage2D
#define glColorMaterial pglColorMaterial #define glColorMaterial pglColorMaterial
@ -119,11 +120,13 @@
#define glMultMatrixf pglMultMatrixf #define glMultMatrixf pglMultMatrixf
#define glNormal3f pglNormal3f #define glNormal3f pglNormal3f
#define glNormal3fv pglNormal3fv #define glNormal3fv pglNormal3fv
#define glOrtho pglOrtho
#define glPixelStorei pglPixelStorei #define glPixelStorei pglPixelStorei
#define glPolygonMode pglPolygonMode #define glPolygonMode pglPolygonMode
#define glPolygonOffset pglPolygonOffset #define glPolygonOffset pglPolygonOffset
#define glPopMatrix pglPopMatrix #define glPopMatrix pglPopMatrix
#define glPushMatrix pglPushMatrix #define glPushMatrix pglPushMatrix
#define glRasterPos2i pglRasterPos2i
#define glRasterPos3d pglRasterPos3d #define glRasterPos3d pglRasterPos3d
#define glReadBuffer pglReadBuffer #define glReadBuffer pglReadBuffer
#define glReadPixels pglReadPixels #define glReadPixels pglReadPixels

View File

@ -351,6 +351,7 @@ void DDRAW_dump_surface_desc(const DDSURFACEDESC2 *lpddsd)
ME(DDSD_LINEARSIZE, DDRAW_dump_DWORD, u1.dwLinearSize), ME(DDSD_LINEARSIZE, DDRAW_dump_DWORD, u1.dwLinearSize),
ME(DDSD_BACKBUFFERCOUNT, DDRAW_dump_DWORD, dwBackBufferCount), ME(DDSD_BACKBUFFERCOUNT, DDRAW_dump_DWORD, dwBackBufferCount),
ME(DDSD_MIPMAPCOUNT, DDRAW_dump_DWORD, u2.dwMipMapCount), ME(DDSD_MIPMAPCOUNT, DDRAW_dump_DWORD, u2.dwMipMapCount),
ME(DDSD_ZBUFFERBITDEPTH, DDRAW_dump_DWORD, u2.dwMipMapCount), /* This is for 'old-style' D3D */
ME(DDSD_REFRESHRATE, DDRAW_dump_DWORD, u2.dwRefreshRate), ME(DDSD_REFRESHRATE, DDRAW_dump_DWORD, u2.dwRefreshRate),
ME(DDSD_ALPHABITDEPTH, DDRAW_dump_DWORD, dwAlphaBitDepth), ME(DDSD_ALPHABITDEPTH, DDRAW_dump_DWORD, dwAlphaBitDepth),
ME(DDSD_LPSURFACE, DDRAW_dump_PTR, lpSurface), ME(DDSD_LPSURFACE, DDRAW_dump_PTR, lpSurface),