[D3D] Some texturing work...
Lionel Ulmer
lionel.ulmer at free.fr
Fri May 9 14:07:26 CDT 2003
Hi all,
See the changelog :-)
Changelog:
- added mipmapping support
- added locking for concurrent access to the D3D device
- improved tracing
- added support for most texture combine stages (inspired by the D3D8 code)
- disable current lock / unlock code pending proper solution
--
Lionel Ulmer - http://www.bbrox.org/
-------------- next part --------------
Index: dlls/ddraw/d3d_private.h
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/d3d_private.h,v
retrieving revision 1.29
diff -u -r1.29 d3d_private.h
--- dlls/ddraw/d3d_private.h 12 Feb 2003 21:40:25 -0000 1.29
+++ dlls/ddraw/d3d_private.h 9 May 2003 18:58:06 -0000
@@ -246,6 +246,9 @@
D3DMATRIX *world_mat, D3DMATRIX *view_mat, D3DMATRIX *proj_mat);
STATEBLOCK state_block;
+
+ /* Used to prevent locks and rendering to overlap */
+ CRITICAL_SECTION crit;
};
/*****************************************************************************
Index: dlls/ddraw/d3dtexture.c
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/d3dtexture.c,v
retrieving revision 1.43
diff -u -r1.43 d3dtexture.c
--- dlls/ddraw/d3dtexture.c 8 May 2003 21:03:57 -0000 1.43
+++ dlls/ddraw/d3dtexture.c 9 May 2003 18:58:07 -0000
@@ -49,7 +49,7 @@
char buf[128];
FILE *f;
- sprintf(buf, "tex_%05d.pnm", glThis->tex_name);
+ sprintf(buf, "tex_%05d_%02d.pnm", glThis->tex_name, This->mipmap_level);
f = fopen(buf, "wb");
DDRAW_dump_surface_to_disk(This, f);
}
@@ -60,6 +60,25 @@
#endif
+static IDirectDrawSurfaceImpl *
+get_sub_mimaplevel(IDirectDrawSurfaceImpl *tex_ptr)
+{
+ /* Now go down the mipmap chain to the next surface */
+ static const DDSCAPS2 mipmap_caps = { DDSCAPS_MIPMAP | DDSCAPS_TEXTURE, 0, 0, 0 };
+ LPDIRECTDRAWSURFACE7 next_level;
+ IDirectDrawSurfaceImpl *surf_ptr;
+ HRESULT hr;
+
+ hr = IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(tex_ptr, IDirectDrawSurface7),
+ (DDSCAPS2 *) &mipmap_caps, &next_level);
+ if (FAILED(hr)) return NULL;
+
+ surf_ptr = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, next_level);
+ IDirectDrawSurface7_Release(next_level);
+
+ return surf_ptr;
+}
+
/*******************************************************************************
* IDirectSurface callback methods
*/
@@ -69,416 +88,435 @@
#if 0
static BOOL color_table_queried = FALSE;
#endif
- void (*ptr_ColorTableEXT) (GLenum target, GLenum internalformat,
- GLsizei width, GLenum format, GLenum type, const GLvoid *table) = NULL;
- BOOL upload_done = FALSE;
- BOOL error = FALSE;
- GLenum format = GL_RGBA, pixel_format = GL_UNSIGNED_BYTE; /* This is only to prevent warnings.. */
- VOID *surface = NULL;
-
- DDSURFACEDESC *src_d = (DDSURFACEDESC *)&(This->surface_desc);
-
- glBindTexture(GL_TEXTURE_2D, glThis->tex_name);
-
- if (glThis->dirty_flag == FALSE) {
- TRACE(" activating OpenGL texture id %d.\n", glThis->tex_name);
- return DD_OK;
- } else {
- TRACE(" activating and uploading texture id %d (initial done = %d).\n", glThis->tex_name, glThis->initial_upload_done);
- }
-
- /* Texture snooping for the curious :-) */
- snoop_texture(This);
+ static void (*ptr_ColorTableEXT) (GLenum target, GLenum internalformat,
+ GLsizei width, GLenum format, GLenum type, const GLvoid *table) = NULL;
+ IDirectDrawSurfaceImpl *surf_ptr;
+ GLuint tex_name = glThis->tex_name;
- if (src_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
- /* ****************
- Paletted Texture
- **************** */
- IDirectDrawPaletteImpl* pal = This->palette;
- BYTE table[256][4];
- int i;
+ TRACE(" activating OpenGL texture id %d.\n", tex_name);
+ glBindTexture(GL_TEXTURE_2D, tex_name);
-#if 0
- if (color_table_queried == FALSE) {
- ptr_ColorTableEXT =
- ((Mesa_DeviceCapabilities *) ((x11_dd_private *) This->surface->s.ddraw->d->private)->device_capabilities)->ptr_ColorTableEXT;
- }
-#endif
+ if (This->mipmap_level != 0) {
+ WARN(" application activating a sub-level of the mipmapping chain (level %d) !\n", This->mipmap_level);
+ }
+
+ surf_ptr = This;
+ while (surf_ptr != NULL) {
+ GLenum format = GL_RGBA, pixel_format = GL_UNSIGNED_BYTE; /* This is only to prevent warnings.. */
+ VOID *surface = NULL;
+ DDSURFACEDESC *src_d = (DDSURFACEDESC *)&(surf_ptr->surface_desc);
+ IDirect3DTextureGLImpl *gl_surf_ptr = (IDirect3DTextureGLImpl *) surf_ptr->tex_private;
+ BOOL upload_done = FALSE;
+ BOOL error = FALSE;
- if (pal == NULL) {
- /* Upload a black texture. The real one will be uploaded on palette change */
- WARN("Palettized texture Loading with a NULL palette !\n");
- memset(table, 0, 256 * 4);
+ if (gl_surf_ptr->dirty_flag == FALSE) {
+ TRACE(" - level %d already uploaded.\n", surf_ptr->mipmap_level);
} else {
- /* Get the surface's palette */
- for (i = 0; i < 256; i++) {
- table[i][0] = pal->palents[i].peRed;
- table[i][1] = pal->palents[i].peGreen;
- table[i][2] = pal->palents[i].peBlue;
- if ((src_d->dwFlags & DDSD_CKSRCBLT) &&
- (i >= src_d->ddckCKSrcBlt.dwColorSpaceLowValue) &&
- (i <= src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
- /* We should maybe here put a more 'neutral' color than the standard bright purple
- one often used by application to prevent the nice purple borders when bi-linear
- filtering is on */
- table[i][3] = 0x00;
- else
- table[i][3] = 0xFF;
- }
- }
+ TRACE(" - uploading texture level %d (initial done = %d).\n",
+ surf_ptr->mipmap_level, gl_surf_ptr->initial_upload_done);
- if (ptr_ColorTableEXT != NULL) {
- /* use Paletted Texture Extension */
- ptr_ColorTableEXT(GL_TEXTURE_2D, /* target */
- GL_RGBA, /* internal format */
- 256, /* table size */
- GL_RGBA, /* table format */
- GL_UNSIGNED_BYTE, /* table type */
- table); /* the color table */
-
- glTexImage2D(GL_TEXTURE_2D, /* target */
- This->mipmap_level, /* level */
- GL_COLOR_INDEX8_EXT, /* internal format */
- src_d->dwWidth, src_d->dwHeight, /* width, height */
- 0, /* border */
- GL_COLOR_INDEX, /* texture format */
- GL_UNSIGNED_BYTE, /* texture type */
- src_d->lpSurface); /* the texture */
-
- upload_done = TRUE;
- } else {
- DWORD i;
- BYTE *src = (BYTE *) src_d->lpSurface, *dst;
-
- surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(DWORD));
- dst = (BYTE *) surface;
-
- for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
- BYTE color = *src++;
- *dst++ = table[color][0];
- *dst++ = table[color][1];
- *dst++ = table[color][2];
- *dst++ = table[color][3];
- }
-
- format = GL_RGBA;
- pixel_format = GL_UNSIGNED_BYTE;
- }
- } else if (src_d->ddpfPixelFormat.dwFlags & DDPF_RGB) {
- /* ************
- RGB Textures
- ************ */
- if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 8) {
- if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0xE0) &&
- (src_d->ddpfPixelFormat.u3.dwGBitMask == 0x1C) &&
- (src_d->ddpfPixelFormat.u4.dwBBitMask == 0x03)) {
- /* **********************
- GL_UNSIGNED_BYTE_3_3_2
- ********************** */
- if (src_d->dwFlags & DDSD_CKSRCBLT) {
- /* This texture format will never be used.. So do not care about color keying
- up until the point in time it will be needed :-) */
- error = TRUE;
- } else {
- format = GL_RGB;
- pixel_format = GL_UNSIGNED_BYTE_3_3_2;
- }
- } else {
- error = TRUE;
- }
- } else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 16) {
- if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0xF800) &&
- (src_d->ddpfPixelFormat.u3.dwGBitMask == 0x07E0) &&
- (src_d->ddpfPixelFormat.u4.dwBBitMask == 0x001F) &&
- (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0000)) {
- if (src_d->dwFlags & DDSD_CKSRCBLT) {
- /* Converting the 565 format in 5551 packed to emulate color-keying.
-
- Note : in all these conversion, it would be best to average the averaging
- pixels to get the color of the pixel that will be color-keyed to
- prevent 'color bleeding'. This will be done later on if ever it is
- too visible.
-
- Note2: when using color-keying + alpha, are the alpha bits part of the
- color-space or not ?
- */
- DWORD i;
- WORD *src = (WORD *) src_d->lpSurface, *dst;
-
- surface = (WORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(WORD));
- dst = (WORD *) surface;
- for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
- WORD color = *src++;
- *dst = ((color & 0xFFC0) | ((color & 0x1F) << 1));
- if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
- (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
- *dst |= 0x0001;
- dst++;
- }
+ /* Texture snooping for the curious :-) */
+ snoop_texture(surf_ptr);
+
+ if (src_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
+ /* ****************
+ Paletted Texture
+ **************** */
+ IDirectDrawPaletteImpl* pal = surf_ptr->palette;
+ BYTE table[256][4];
+ int i;
- format = GL_RGBA;
- pixel_format = GL_UNSIGNED_SHORT_5_5_5_1;
- } else {
- format = GL_RGB;
- pixel_format = GL_UNSIGNED_SHORT_5_6_5;
- }
- } else if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0xF800) &&
- (src_d->ddpfPixelFormat.u3.dwGBitMask == 0x07C0) &&
- (src_d->ddpfPixelFormat.u4.dwBBitMask == 0x003E) &&
- (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0001)) {
- format = GL_RGBA;
- pixel_format = GL_UNSIGNED_SHORT_5_5_5_1;
- if (src_d->dwFlags & DDSD_CKSRCBLT) {
- /* Change the alpha value of the color-keyed pixels to emulate color-keying. */
- DWORD i;
- WORD *src = (WORD *) src_d->lpSurface, *dst;
-
- surface = (WORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(WORD));
- dst = (WORD *) surface;
- for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
- WORD color = *src++;
- *dst = color & 0xFFFE;
- if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
- (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
- *dst |= color & 0x0001;
- dst++;
- }
- }
- } else if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0xF000) &&
- (src_d->ddpfPixelFormat.u3.dwGBitMask == 0x0F00) &&
- (src_d->ddpfPixelFormat.u4.dwBBitMask == 0x00F0) &&
- (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x000F)) {
- format = GL_RGBA;
- pixel_format = GL_UNSIGNED_SHORT_4_4_4_4;
- if (src_d->dwFlags & DDSD_CKSRCBLT) {
- /* Change the alpha value of the color-keyed pixels to emulate color-keying. */
- DWORD i;
- WORD *src = (WORD *) src_d->lpSurface, *dst;
-
- surface = (WORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(WORD));
- dst = (WORD *) surface;
- for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
- WORD color = *src++;
- *dst = color & 0xFFF0;
- if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
- (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
- *dst |= color & 0x000F;
- dst++;
- }
+#if 0
+ if (color_table_queried == FALSE) {
+ ptr_ColorTableEXT =
+ ((Mesa_DeviceCapabilities *) ((x11_dd_private *) surf_ptr->surface->s.ddraw->d->private)->device_capabilities)->ptr_ColorTableEXT;
}
- } else if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0x0F00) &&
- (src_d->ddpfPixelFormat.u3.dwGBitMask == 0x00F0) &&
- (src_d->ddpfPixelFormat.u4.dwBBitMask == 0x000F) &&
- (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0xF000)) {
- /* Move the four Alpha bits... */
- DWORD i;
- WORD *src = (WORD *) src_d->lpSurface, *dst;
-
- surface = (WORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(WORD));
- dst = surface;
+#endif
- if (src_d->dwFlags & DDSD_CKSRCBLT) {
- for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
- WORD color = *src++;
- *dst = (color & 0x0FFF) << 4;
- if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
- (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
- *dst |= (color & 0xF000) >> 12;
- dst++;
- }
+ if (pal == NULL) {
+ /* Upload a black texture. The real one will be uploaded on palette change */
+ WARN("Palettized texture Loading with a NULL palette !\n");
+ memset(table, 0, 256 * 4);
} else {
- for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
- WORD color = *src++;
- *dst++ = (((color & 0x0FFF) << 4) |
- ((color & 0xF000) >> 12));
+ /* Get the surface's palette */
+ for (i = 0; i < 256; i++) {
+ table[i][0] = pal->palents[i].peRed;
+ table[i][1] = pal->palents[i].peGreen;
+ table[i][2] = pal->palents[i].peBlue;
+ if ((src_d->dwFlags & DDSD_CKSRCBLT) &&
+ (i >= src_d->ddckCKSrcBlt.dwColorSpaceLowValue) &&
+ (i <= src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
+ /* We should maybe here put a more 'neutral' color than the standard bright purple
+ one often used by application to prevent the nice purple borders when bi-linear
+ filtering is on */
+ table[i][3] = 0x00;
+ else
+ table[i][3] = 0xFF;
}
}
- format = GL_RGBA;
- pixel_format = GL_UNSIGNED_SHORT_4_4_4_4;
- } else if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0x7C00) &&
- (src_d->ddpfPixelFormat.u3.dwGBitMask == 0x03E0) &&
- (src_d->ddpfPixelFormat.u4.dwBBitMask == 0x001F) &&
- (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x8000)) {
- /* Converting the 1555 format in 5551 packed */
- DWORD i;
- WORD *src = (WORD *) src_d->lpSurface, *dst;
-
- surface = (WORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(WORD));
- dst = (WORD *) surface;
-
- if (src_d->dwFlags & DDSD_CKSRCBLT) {
- for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
- WORD color = *src++;
- *dst = (color & 0x7FFF) << 1;
- if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
- (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
- *dst |= (color & 0x8000) >> 15;
- dst++;
- }
+ if (ptr_ColorTableEXT != NULL) {
+ /* use Paletted Texture Extension */
+ ptr_ColorTableEXT(GL_TEXTURE_2D, /* target */
+ GL_RGBA, /* internal format */
+ 256, /* table size */
+ GL_RGBA, /* table format */
+ GL_UNSIGNED_BYTE, /* table type */
+ table); /* the color table */
+
+ glTexImage2D(GL_TEXTURE_2D, /* target */
+ surf_ptr->mipmap_level, /* level */
+ GL_COLOR_INDEX8_EXT, /* internal format */
+ src_d->dwWidth, src_d->dwHeight, /* width, height */
+ 0, /* border */
+ GL_COLOR_INDEX, /* texture format */
+ GL_UNSIGNED_BYTE, /* texture type */
+ src_d->lpSurface); /* the texture */
+
+ upload_done = TRUE;
} else {
- for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
- WORD color = *src++;
- *dst++ = (((color & 0x7FFF) << 1) |
- ((color & 0x8000) >> 15));
- }
- }
-
- format = GL_RGBA;
- pixel_format = GL_UNSIGNED_SHORT_5_5_5_1;
- } else {
- error = TRUE;
- }
- } else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 24) {
- if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0x00FF0000) &&
- (src_d->ddpfPixelFormat.u3.dwGBitMask == 0x0000FF00) &&
- (src_d->ddpfPixelFormat.u4.dwBBitMask == 0x000000FF) &&
- (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000000)) {
- if (src_d->dwFlags & DDSD_CKSRCBLT) {
- /* This is a pain :-) */
DWORD i;
- BYTE *src = (BYTE *) src_d->lpSurface;
- DWORD *dst;
+ BYTE *src = (BYTE *) src_d->lpSurface, *dst;
+
+ surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(DWORD));
+ dst = (BYTE *) surface;
- surface = (DWORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(DWORD));
- dst = (DWORD *) surface;
for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
- DWORD color = *((DWORD *) src) & 0x00FFFFFF;
- src += 3;
- *dst = *src++ << 8;
- if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
- (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
- *dst |= 0xFF;
- dst++;
+ BYTE color = *src++;
+ *dst++ = table[color][0];
+ *dst++ = table[color][1];
+ *dst++ = table[color][2];
+ *dst++ = table[color][3];
}
+
format = GL_RGBA;
- pixel_format = GL_UNSIGNED_INT_8_8_8_8;
+ pixel_format = GL_UNSIGNED_BYTE;
+ }
+ } else if (src_d->ddpfPixelFormat.dwFlags & DDPF_RGB) {
+ /* ************
+ RGB Textures
+ ************ */
+ if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 8) {
+ if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0xE0) &&
+ (src_d->ddpfPixelFormat.u3.dwGBitMask == 0x1C) &&
+ (src_d->ddpfPixelFormat.u4.dwBBitMask == 0x03)) {
+ /* **********************
+ GL_UNSIGNED_BYTE_3_3_2
+ ********************** */
+ if (src_d->dwFlags & DDSD_CKSRCBLT) {
+ /* This texture format will never be used.. So do not care about color keying
+ up until the point in time it will be needed :-) */
+ error = TRUE;
+ } else {
+ format = GL_RGB;
+ pixel_format = GL_UNSIGNED_BYTE_3_3_2;
+ }
+ } else {
+ error = TRUE;
+ }
+ } else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 16) {
+ if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0xF800) &&
+ (src_d->ddpfPixelFormat.u3.dwGBitMask == 0x07E0) &&
+ (src_d->ddpfPixelFormat.u4.dwBBitMask == 0x001F) &&
+ (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0000)) {
+ if (src_d->dwFlags & DDSD_CKSRCBLT) {
+ /* Converting the 565 format in 5551 packed to emulate color-keying.
+
+ Note : in all these conversion, it would be best to average the averaging
+ pixels to get the color of the pixel that will be color-keyed to
+ prevent 'color bleeding'. This will be done later on if ever it is
+ too visible.
+
+ Note2: when using color-keying + alpha, are the alpha bits part of the
+ color-space or not ?
+ */
+ DWORD i;
+ WORD *src = (WORD *) src_d->lpSurface, *dst;
+
+ surface = (WORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+ src_d->dwWidth * src_d->dwHeight * sizeof(WORD));
+ dst = (WORD *) surface;
+ for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
+ WORD color = *src++;
+ *dst = ((color & 0xFFC0) | ((color & 0x1F) << 1));
+ if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
+ (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
+ *dst |= 0x0001;
+ dst++;
+ }
+
+ format = GL_RGBA;
+ pixel_format = GL_UNSIGNED_SHORT_5_5_5_1;
+ } else {
+ format = GL_RGB;
+ pixel_format = GL_UNSIGNED_SHORT_5_6_5;
+ }
+ } else if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0xF800) &&
+ (src_d->ddpfPixelFormat.u3.dwGBitMask == 0x07C0) &&
+ (src_d->ddpfPixelFormat.u4.dwBBitMask == 0x003E) &&
+ (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0001)) {
+ format = GL_RGBA;
+ pixel_format = GL_UNSIGNED_SHORT_5_5_5_1;
+ if (src_d->dwFlags & DDSD_CKSRCBLT) {
+ /* Change the alpha value of the color-keyed pixels to emulate color-keying. */
+ DWORD i;
+ WORD *src = (WORD *) src_d->lpSurface, *dst;
+
+ surface = (WORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+ src_d->dwWidth * src_d->dwHeight * sizeof(WORD));
+ dst = (WORD *) surface;
+ for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
+ WORD color = *src++;
+ *dst = color & 0xFFFE;
+ if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
+ (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
+ *dst |= color & 0x0001;
+ dst++;
+ }
+ }
+ } else if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0xF000) &&
+ (src_d->ddpfPixelFormat.u3.dwGBitMask == 0x0F00) &&
+ (src_d->ddpfPixelFormat.u4.dwBBitMask == 0x00F0) &&
+ (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x000F)) {
+ format = GL_RGBA;
+ pixel_format = GL_UNSIGNED_SHORT_4_4_4_4;
+ if (src_d->dwFlags & DDSD_CKSRCBLT) {
+ /* Change the alpha value of the color-keyed pixels to emulate color-keying. */
+ DWORD i;
+ WORD *src = (WORD *) src_d->lpSurface, *dst;
+
+ surface = (WORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+ src_d->dwWidth * src_d->dwHeight * sizeof(WORD));
+ dst = (WORD *) surface;
+ for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
+ WORD color = *src++;
+ *dst = color & 0xFFF0;
+ if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
+ (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
+ *dst |= color & 0x000F;
+ dst++;
+ }
+ }
+ } else if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0x0F00) &&
+ (src_d->ddpfPixelFormat.u3.dwGBitMask == 0x00F0) &&
+ (src_d->ddpfPixelFormat.u4.dwBBitMask == 0x000F) &&
+ (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0xF000)) {
+ /* Move the four Alpha bits... */
+ DWORD i;
+ WORD *src = (WORD *) src_d->lpSurface, *dst;
+
+ surface = (WORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+ src_d->dwWidth * src_d->dwHeight * sizeof(WORD));
+ dst = surface;
+
+ if (src_d->dwFlags & DDSD_CKSRCBLT) {
+ for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
+ WORD color = *src++;
+ *dst = (color & 0x0FFF) << 4;
+ if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
+ (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
+ *dst |= (color & 0xF000) >> 12;
+ dst++;
+ }
+ } else {
+ for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
+ WORD color = *src++;
+ *dst++ = (((color & 0x0FFF) << 4) |
+ ((color & 0xF000) >> 12));
+ }
+ }
+
+ format = GL_RGBA;
+ pixel_format = GL_UNSIGNED_SHORT_4_4_4_4;
+ } else if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0x7C00) &&
+ (src_d->ddpfPixelFormat.u3.dwGBitMask == 0x03E0) &&
+ (src_d->ddpfPixelFormat.u4.dwBBitMask == 0x001F) &&
+ (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x8000)) {
+ /* Converting the 1555 format in 5551 packed */
+ DWORD i;
+ WORD *src = (WORD *) src_d->lpSurface, *dst;
+
+ surface = (WORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+ src_d->dwWidth * src_d->dwHeight * sizeof(WORD));
+ dst = (WORD *) surface;
+
+ if (src_d->dwFlags & DDSD_CKSRCBLT) {
+ for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
+ WORD color = *src++;
+ *dst = (color & 0x7FFF) << 1;
+ if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
+ (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
+ *dst |= (color & 0x8000) >> 15;
+ dst++;
+ }
+ } else {
+ for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
+ WORD color = *src++;
+ *dst++ = (((color & 0x7FFF) << 1) |
+ ((color & 0x8000) >> 15));
+ }
+ }
+
+ format = GL_RGBA;
+ pixel_format = GL_UNSIGNED_SHORT_5_5_5_1;
+ } else {
+ error = TRUE;
+ }
+ } else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 24) {
+ if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0x00FF0000) &&
+ (src_d->ddpfPixelFormat.u3.dwGBitMask == 0x0000FF00) &&
+ (src_d->ddpfPixelFormat.u4.dwBBitMask == 0x000000FF) &&
+ (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000000)) {
+ if (src_d->dwFlags & DDSD_CKSRCBLT) {
+ /* This is a pain :-) */
+ DWORD i;
+ BYTE *src = (BYTE *) src_d->lpSurface;
+ DWORD *dst;
+
+ surface = (DWORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+ src_d->dwWidth * src_d->dwHeight * sizeof(DWORD));
+ dst = (DWORD *) surface;
+ for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
+ DWORD color = *((DWORD *) src) & 0x00FFFFFF;
+ src += 3;
+ *dst = *src++ << 8;
+ if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
+ (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
+ *dst |= 0xFF;
+ dst++;
+ }
+ format = GL_RGBA;
+ pixel_format = GL_UNSIGNED_INT_8_8_8_8;
+ } else {
+ format = GL_BGR;
+ pixel_format = GL_UNSIGNED_BYTE;
+ }
+ } else {
+ error = TRUE;
+ }
+ } else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 32) {
+ if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0xFF000000) &&
+ (src_d->ddpfPixelFormat.u3.dwGBitMask == 0x00FF0000) &&
+ (src_d->ddpfPixelFormat.u4.dwBBitMask == 0x0000FF00) &&
+ (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x000000FF)) {
+ if (src_d->dwFlags & DDSD_CKSRCBLT) {
+ /* Just use the alpha component to handle color-keying... */
+ DWORD i;
+ DWORD *src = (DWORD *) src_d->lpSurface, *dst;
+
+ surface = (DWORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+ src_d->dwWidth * src_d->dwHeight * sizeof(DWORD));
+ dst = (DWORD *) surface;
+ for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
+ DWORD color = *src++;
+ *dst = color & 0xFFFFFF00;
+ if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
+ (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
+ *dst |= color & 0x000000FF;
+ dst++;
+ }
+ }
+ format = GL_RGBA;
+ pixel_format = GL_UNSIGNED_INT_8_8_8_8;
+ } else if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0x00FF0000) &&
+ (src_d->ddpfPixelFormat.u3.dwGBitMask == 0x0000FF00) &&
+ (src_d->ddpfPixelFormat.u4.dwBBitMask == 0x000000FF) &&
+ (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0xFF000000)) {
+ /* Convert from ARGB (Windows' format) to RGBA.
+ Note: need to check for GL extensions handling ARGB instead of always converting */
+ DWORD i;
+ DWORD *src = (DWORD *) src_d->lpSurface, *dst;
+
+ surface = (DWORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(DWORD));
+ dst = (DWORD *) surface;
+ if (src_d->dwFlags & DDSD_CKSRCBLT) {
+ for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
+ DWORD color = *src++;
+ *dst = (color & 0x00FFFFFF) << 8;
+ if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
+ (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
+ *dst |= (color & 0xFF000000) >> 24;
+ dst++;
+ }
+ } else {
+ for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
+ DWORD color = *src++;
+ *dst = (color & 0x00FFFFFF) << 8;
+ *dst |= (color & 0xFF000000) >> 24;
+ }
+ }
+ format = GL_RGBA;
+ pixel_format = GL_UNSIGNED_INT_8_8_8_8;
+ } else if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0x00FF0000) &&
+ (src_d->ddpfPixelFormat.u3.dwGBitMask == 0x0000FF00) &&
+ (src_d->ddpfPixelFormat.u4.dwBBitMask == 0x000000FF) &&
+ (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000000)) {
+ /* Just add an alpha component and handle color-keying... */
+ DWORD i;
+ DWORD *src = (DWORD *) src_d->lpSurface, *dst;
+
+ surface = (DWORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(DWORD));
+ dst = (DWORD *) surface;
+
+ if (src_d->dwFlags & DDSD_CKSRCBLT) {
+ for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
+ DWORD color = *src++;
+ *dst = color << 8;
+ if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
+ (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
+ *dst |= 0xFF;
+ dst++;
+ }
+ } else {
+ for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
+ *dst++ = (*src++ << 8) | 0xFF;
+ }
+ }
+ format = GL_RGBA;
+ pixel_format = GL_UNSIGNED_INT_8_8_8_8;
+ } else {
+ error = TRUE;
+ }
} else {
- format = GL_BGR;
- pixel_format = GL_UNSIGNED_BYTE;
+ error = TRUE;
}
} else {
error = TRUE;
- }
- } else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 32) {
- if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0xFF000000) &&
- (src_d->ddpfPixelFormat.u3.dwGBitMask == 0x00FF0000) &&
- (src_d->ddpfPixelFormat.u4.dwBBitMask == 0x0000FF00) &&
- (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x000000FF)) {
- if (src_d->dwFlags & DDSD_CKSRCBLT) {
- /* Just use the alpha component to handle color-keying... */
- DWORD i;
- DWORD *src = (DWORD *) src_d->lpSurface, *dst;
-
- surface = (DWORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(DWORD));
- dst = (DWORD *) surface;
- for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
- DWORD color = *src++;
- *dst = color & 0xFFFFFF00;
- if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
- (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
- *dst |= color & 0x000000FF;
- dst++;
- }
- }
- format = GL_RGBA;
- pixel_format = GL_UNSIGNED_INT_8_8_8_8;
- } else if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0x00FF0000) &&
- (src_d->ddpfPixelFormat.u3.dwGBitMask == 0x0000FF00) &&
- (src_d->ddpfPixelFormat.u4.dwBBitMask == 0x000000FF) &&
- (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0xFF000000)) {
- /* Convert from ARGB (Windows' format) to RGBA.
- Note: need to check for GL extensions handling ARGB instead of always converting */
- DWORD i;
- DWORD *src = (DWORD *) src_d->lpSurface, *dst;
-
- surface = (DWORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(DWORD));
- dst = (DWORD *) surface;
- if (src_d->dwFlags & DDSD_CKSRCBLT) {
- for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
- DWORD color = *src++;
- *dst = (color & 0x00FFFFFF) << 8;
- if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
- (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
- *dst |= (color & 0xFF000000) >> 24;
- dst++;
- }
+ }
+
+ if ((upload_done == FALSE) && (error == FALSE)) {
+ if (gl_surf_ptr->initial_upload_done == FALSE) {
+ glTexImage2D(GL_TEXTURE_2D,
+ surf_ptr->mipmap_level,
+ format,
+ src_d->dwWidth, src_d->dwHeight,
+ 0,
+ format,
+ pixel_format,
+ surface == NULL ? src_d->lpSurface : surface);
+ gl_surf_ptr->initial_upload_done = TRUE;
} else {
- for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
- DWORD color = *src++;
- *dst = (color & 0x00FFFFFF) << 8;
- *dst |= (color & 0xFF000000) >> 24;
- }
+ glTexSubImage2D(GL_TEXTURE_2D,
+ surf_ptr->mipmap_level,
+ 0, 0,
+ src_d->dwWidth, src_d->dwHeight,
+ format,
+ pixel_format,
+ surface == NULL ? src_d->lpSurface : surface);
}
- format = GL_RGBA;
- pixel_format = GL_UNSIGNED_INT_8_8_8_8;
- } else if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0x00FF0000) &&
- (src_d->ddpfPixelFormat.u3.dwGBitMask == 0x0000FF00) &&
- (src_d->ddpfPixelFormat.u4.dwBBitMask == 0x000000FF) &&
- (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000000)) {
- /* Just add an alpha component and handle color-keying... */
- DWORD i;
- DWORD *src = (DWORD *) src_d->lpSurface, *dst;
+ gl_surf_ptr->dirty_flag = FALSE;
- surface = (DWORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(DWORD));
- dst = (DWORD *) surface;
-
- if (src_d->dwFlags & DDSD_CKSRCBLT) {
- for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
- DWORD color = *src++;
- *dst = color << 8;
- if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
- (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
- *dst |= 0xFF;
- dst++;
- }
- } else {
- for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
- *dst++ = (*src++ << 8) | 0xFF;
- }
+ if (surface) HeapFree(GetProcessHeap(), 0, surface);
+ } else if (error == TRUE) {
+ if (ERR_ON(ddraw)) {
+ ERR(" unsupported pixel format for textures : \n");
+ DDRAW_dump_pixelformat(&src_d->ddpfPixelFormat);
}
- format = GL_RGBA;
- pixel_format = GL_UNSIGNED_INT_8_8_8_8;
- } else {
- error = TRUE;
}
- } else {
- error = TRUE;
- }
- } else {
- error = TRUE;
- }
-
- if ((upload_done == FALSE) && (error == FALSE)) {
- if (glThis->initial_upload_done == FALSE) {
- glTexImage2D(GL_TEXTURE_2D,
- This->mipmap_level,
- format,
- src_d->dwWidth, src_d->dwHeight,
- 0,
- format,
- pixel_format,
- surface == NULL ? src_d->lpSurface : surface);
- glThis->initial_upload_done = TRUE;
- } else {
- glTexSubImage2D(GL_TEXTURE_2D,
- This->mipmap_level,
- 0, 0,
- src_d->dwWidth, src_d->dwHeight,
- format,
- pixel_format,
- surface == NULL ? src_d->lpSurface : surface);
}
-
- if (surface) HeapFree(GetProcessHeap(), 0, surface);
- } else if (error == TRUE) {
- if (ERR_ON(ddraw)) {
- ERR("Unsupported pixel format for textures : \n");
- DDRAW_dump_pixelformat(&src_d->ddpfPixelFormat);
- }
- }
- glThis->dirty_flag = FALSE;
+ surf_ptr = get_sub_mimaplevel(surf_ptr);
+ }
return DD_OK;
}
@@ -499,7 +537,8 @@
IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
glThis->dirty_flag = TRUE;
-
+ /* TODO: check color-keying on mipmapped surfaces... */
+
return DD_OK;
}
@@ -560,6 +599,8 @@
/* And set the dirty flag */
glThis->dirty_flag = TRUE;
+
+ /* TODO: check palette on mipmapped surfaces... */
}
static void
@@ -618,82 +659,99 @@
LPDIRECT3DTEXTURE2 lpD3DTexture2)
{
ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface);
- IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
- IDirectDrawSurfaceImpl *lpD3DTextureImpl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, lpD3DTexture2);
- DWORD mem_used;
- DDSURFACEDESC *src_d, *dst_d;
+ IDirectDrawSurfaceImpl *src_ptr = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, lpD3DTexture2);
+ IDirectDrawSurfaceImpl *dst_ptr = This;
HRESULT ret_value = D3D_OK;
-
+
TRACE("(%p/%p)->(%p)\n", This, iface, lpD3DTexture2);
- if (glThis != NULL) {
- if (glThis->loaded == FALSE) {
- /* Only check memory for not already loaded texture... */
- mem_used = This->surface_desc.dwHeight *
- This->surface_desc.u1.lPitch;
- if (This->ddraw_owner->allocate_memory(This->ddraw_owner, mem_used) < 0) {
- TRACE(" out of virtual memory... Warning application.\n");
- return D3DERR_TEXTURE_LOAD_FAILED;
+ if (((src_ptr->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) != (dst_ptr->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)) ||
+ (src_ptr->surface_desc.u2.dwMipMapCount != dst_ptr->surface_desc.u2.dwMipMapCount)) {
+ ERR("Trying to load surfaces with different mip-map counts !\n");
+ }
+
+ /* Now loop through all mipmap levels and load all of them... */
+ while (1) {
+ IDirect3DTextureGLImpl *gl_dst_ptr = (IDirect3DTextureGLImpl *) dst_ptr->tex_private;
+ DDSURFACEDESC *src_d, *dst_d;
+
+ if (gl_dst_ptr != NULL) {
+ if (gl_dst_ptr->loaded == FALSE) {
+ /* Only check memory for not already loaded texture... */
+ DWORD mem_used = dst_ptr->surface_desc.dwHeight * dst_ptr->surface_desc.u1.lPitch;
+ if (This->ddraw_owner->allocate_memory(This->ddraw_owner, mem_used) < 0) {
+ TRACE(" out of virtual memory... Warning application.\n");
+ return D3DERR_TEXTURE_LOAD_FAILED;
+ }
}
+ gl_dst_ptr->loaded = TRUE;
}
- glThis->loaded = TRUE;
- }
- TRACE("Copied surface %p to surface %p\n", lpD3DTextureImpl, This);
+ TRACE(" copying surface %p to surface %p (mipmap level %d)\n", src_ptr, dst_ptr, src_ptr->mipmap_level);
- if ( This->surface_desc.ddsCaps.dwCaps & DDSCAPS_ALLOCONLOAD )
- /* If the surface is not allocated and its location is not yet specified,
- force it to video memory */
- if ( !(This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_SYSTEMMEMORY|DDSCAPS_VIDEOMEMORY)) )
- This->surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
-
- /* Suppress the ALLOCONLOAD flag */
- This->surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD;
-
- /* After seeing some logs, not sure at all about this... */
- if (This->palette == NULL) {
- This->palette = lpD3DTextureImpl->palette;
- if (lpD3DTextureImpl->palette != NULL) IDirectDrawPalette_AddRef(ICOM_INTERFACE(lpD3DTextureImpl->palette,
- IDirectDrawPalette));
- } else {
- if (lpD3DTextureImpl->palette != NULL) {
- PALETTEENTRY palent[256];
- IDirectDrawPalette *pal_int = ICOM_INTERFACE(lpD3DTextureImpl->palette, IDirectDrawPalette);
- IDirectDrawPalette_GetEntries(pal_int, 0, 0, 256, palent);
- IDirectDrawPalette_SetEntries(ICOM_INTERFACE(This->palette, IDirectDrawPalette),
- 0, 0, 256, palent);
+ if ( dst_ptr->surface_desc.ddsCaps.dwCaps & DDSCAPS_ALLOCONLOAD )
+ /* If the surface is not allocated and its location is not yet specified,
+ force it to video memory */
+ if ( !(dst_ptr->surface_desc.ddsCaps.dwCaps & (DDSCAPS_SYSTEMMEMORY|DDSCAPS_VIDEOMEMORY)) )
+ dst_ptr->surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
+
+ /* Suppress the ALLOCONLOAD flag */
+ dst_ptr->surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD;
+
+ /* After seeing some logs, not sure at all about this... */
+ if (dst_ptr->palette == NULL) {
+ dst_ptr->palette = src_ptr->palette;
+ if (src_ptr->palette != NULL) IDirectDrawPalette_AddRef(ICOM_INTERFACE(src_ptr->palette, IDirectDrawPalette));
+ } else {
+ if (src_ptr->palette != NULL) {
+ PALETTEENTRY palent[256];
+ IDirectDrawPalette_GetEntries(ICOM_INTERFACE(src_ptr->palette, IDirectDrawPalette),
+ 0, 0, 256, palent);
+ IDirectDrawPalette_SetEntries(ICOM_INTERFACE(dst_ptr->palette, IDirectDrawPalette),
+ 0, 0, 256, palent);
+ }
}
- }
-
- /* Copy one surface on the other */
- dst_d = (DDSURFACEDESC *)&(This->surface_desc);
- src_d = (DDSURFACEDESC *)&(lpD3DTextureImpl->surface_desc);
-
- if ((src_d->dwWidth != dst_d->dwWidth) || (src_d->dwHeight != dst_d->dwHeight)) {
- /* Should also check for same pixel format, u1.lPitch, ... */
- ERR("Error in surface sizes\n");
- return D3DERR_TEXTURE_LOAD_FAILED;
- } else {
- /* LPDIRECT3DDEVICE2 d3dd = (LPDIRECT3DDEVICE2) This->D3Ddevice; */
- /* I should put a macro for the calculus of bpp */
-
- /* Copy also the ColorKeying stuff */
- if (src_d->dwFlags & DDSD_CKSRCBLT) {
- dst_d->dwFlags |= DDSD_CKSRCBLT;
- dst_d->ddckCKSrcBlt.dwColorSpaceLowValue = src_d->ddckCKSrcBlt.dwColorSpaceLowValue;
- dst_d->ddckCKSrcBlt.dwColorSpaceHighValue = src_d->ddckCKSrcBlt.dwColorSpaceHighValue;
+
+ /* Copy one surface on the other */
+ dst_d = (DDSURFACEDESC *)&(dst_ptr->surface_desc);
+ src_d = (DDSURFACEDESC *)&(src_ptr->surface_desc);
+
+ if ((src_d->dwWidth != dst_d->dwWidth) || (src_d->dwHeight != dst_d->dwHeight)) {
+ /* Should also check for same pixel format, u1.lPitch, ... */
+ ERR("Error in surface sizes\n");
+ return D3DERR_TEXTURE_LOAD_FAILED;
+ } else {
+ /* LPDIRECT3DDEVICE2 d3dd = (LPDIRECT3DDEVICE2) This->D3Ddevice; */
+ /* I should put a macro for the calculus of bpp */
+
+ /* Copy also the ColorKeying stuff */
+ if (src_d->dwFlags & DDSD_CKSRCBLT) {
+ dst_d->dwFlags |= DDSD_CKSRCBLT;
+ dst_d->ddckCKSrcBlt.dwColorSpaceLowValue = src_d->ddckCKSrcBlt.dwColorSpaceLowValue;
+ dst_d->ddckCKSrcBlt.dwColorSpaceHighValue = src_d->ddckCKSrcBlt.dwColorSpaceHighValue;
+ }
+
+ /* Copy the main memory texture into the surface that corresponds to the OpenGL
+ texture object. */
+ memcpy(dst_d->lpSurface, src_d->lpSurface, src_d->u1.lPitch * src_d->dwHeight);
+
+ if (gl_dst_ptr != NULL) {
+ /* If the GetHandle was not done, it is an error... */
+ if (gl_dst_ptr->tex_name == 0) ERR("Unbound GL texture !!!\n");
+
+ /* Set this texture as dirty */
+ gl_dst_ptr->dirty_flag = TRUE;
+ }
}
- /* Copy the main memory texture into the surface that corresponds to the OpenGL
- texture object. */
- memcpy(dst_d->lpSurface, src_d->lpSurface, src_d->u1.lPitch * src_d->dwHeight);
-
- if (glThis != NULL) {
- /* If the GetHandle was not done, it is an error... */
- if (glThis->tex_name == 0) ERR("Unbound GL texture !!!\n");
+ src_ptr = get_sub_mimaplevel(src_ptr);
+ dst_ptr = get_sub_mimaplevel(dst_ptr);
- /* Set this texture as dirty */
- glThis->dirty_flag = TRUE;
+ if ((src_ptr == NULL) || (dst_ptr == NULL)) {
+ if (src_ptr != dst_ptr) {
+ ERR(" Loading surface with different mipmap structure !!!\n");
+ }
+ break;
}
}
Index: dlls/ddraw/d3ddevice/main.c
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/d3ddevice/main.c,v
retrieving revision 1.38
diff -u -r1.38 main.c
--- dlls/ddraw/d3ddevice/main.c 15 Mar 2003 01:11:15 -0000 1.38
+++ dlls/ddraw/d3ddevice/main.c 9 May 2003 18:58:08 -0000
@@ -132,10 +132,10 @@
};
DWORD InitTextureStageStateTab[] = {
- D3DTSS_COLOROP, D3DTOP_DISABLE,
+ D3DTSS_COLOROP, D3DTOP_DISABLE, /* Note, it's manually set for stage 0 */
D3DTSS_COLORARG1, D3DTA_TEXTURE,
D3DTSS_COLORARG2, D3DTA_CURRENT,
- D3DTSS_ALPHAOP, D3DTOP_DISABLE,
+ D3DTSS_ALPHAOP, D3DTOP_DISABLE, /* Note, it's manually set for stage 0 */
D3DTSS_ALPHAARG1, D3DTA_TEXTURE,
D3DTSS_ALPHAARG2, D3DTA_CURRENT,
/* FIXME: D3DTSS_BUMPENVMAT00,01,10,11 */
@@ -143,13 +143,13 @@
D3DTSS_ADDRESS, D3DTADDRESS_WRAP,
D3DTSS_ADDRESSU, D3DTADDRESS_WRAP,
D3DTSS_ADDRESSV, D3DTADDRESS_WRAP,
- /* FIXME: D3DTSS_BORDERCOLOR */
+ D3DTSS_BORDERCOLOR, 0x00000000,
D3DTSS_MAGFILTER, D3DTFG_POINT,
D3DTSS_MINFILTER, D3DTFN_POINT,
D3DTSS_MIPFILTER, D3DTFP_NONE,
D3DTSS_MIPMAPLODBIAS, 0x00000000, /* 0.0f */
- D3DTSS_MAXMIPLEVEL, 0
- /* FIXME: D3DTSS_MAXANISOTROPY */
+ D3DTSS_MAXMIPLEVEL, 0,
+ D3DTSS_MAXANISOTROPY, 1,
/* FIXME: D3DTSS_BUMPENVLSCALE */
/* FIXME: D3DTSS_NUMPENVLOFFSET */
/* FIXME: D3DTSS_TEXTURETRANSFORMFLAGS */
@@ -158,21 +158,21 @@
void InitDefaultStateBlock(STATEBLOCK* lpStateBlock, int version)
{
- int i,j;
+ int i, j;
TRACE("(%p,%d)\n", lpStateBlock, version);
memset(lpStateBlock, 0, sizeof(STATEBLOCK));
/* Initialize render states */
- for(i = 0; i < sizeof(InitRenderStateTab) / sizeof(InitRenderStateTab[0]); i += 2)
+ for (i = 0; i < sizeof(InitRenderStateTab) / sizeof(InitRenderStateTab[0]); i += 2)
{
lpStateBlock->render_state[InitRenderStateTab[i] - 1] = InitRenderStateTab[i + 1];
lpStateBlock->set_flags.render_state[InitRenderStateTab[i] - 1] = TRUE;
}
/* Initialize texture stages states */
- for(i = 0; i < MAX_TEXTURES; i++)
+ for (i = 0; i < MAX_TEXTURES; i++)
{
- for(j = 0; j < sizeof(InitTextureStageStateTab) / sizeof(InitTextureStageStateTab[0]); j += 2)
+ for (j = 0; j < sizeof(InitTextureStageStateTab) / sizeof(InitTextureStageStateTab[0]); j += 2)
{
lpStateBlock->texture_stage_state[i][InitTextureStageStateTab[j] - 1] = InitTextureStageStateTab[j + 1];
lpStateBlock->set_flags.texture_stage_state[i][InitTextureStageStateTab[j] - 1] = TRUE;
@@ -185,6 +185,8 @@
/* The first texture is particular, update it consequently */
lpStateBlock->texture_stage_state[0][D3DTSS_COLOROP - 1] = D3DTOP_MODULATE;
lpStateBlock->texture_stage_state[0][D3DTSS_ALPHAOP - 1] = D3DTOP_SELECTARG1;
+ lpStateBlock->texture_stage_state[0][D3DTSS_COLORARG2 - 1] = D3DTA_DIFFUSE;
+ lpStateBlock->texture_stage_state[0][D3DTSS_ALPHAARG2 - 1] = D3DTA_DIFFUSE;
/* Updates for particular versions */
if ((version == 1) || (version==2))
Index: dlls/ddraw/d3ddevice/mesa.c
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/d3ddevice/mesa.c,v
retrieving revision 1.93
diff -u -r1.93 mesa.c
--- dlls/ddraw/d3ddevice/mesa.c 8 May 2003 21:03:57 -0000 1.93
+++ dlls/ddraw/d3ddevice/mesa.c 9 May 2003 18:58:09 -0000
@@ -327,6 +327,8 @@
if (This->current_texture[i] != NULL)
IDirectDrawSurface7_Release(ICOM_INTERFACE(This->current_texture[i], IDirectDrawSurface7));
+ /* TODO: remove the 'callbacks' for Flip and Lock/Unlock */
+
/* And warn the D3D object that this device is no longer active... */
This->d3d->removed_device(This->d3d, This);
@@ -334,6 +336,8 @@
HeapFree(GetProcessHeap(), 0, This->view_mat);
HeapFree(GetProcessHeap(), 0, This->proj_mat);
+ DeleteCriticalSection(&(This->crit));
+
ENTER_GL();
glXDestroyContext(glThis->display, glThis->gl_context);
LEAVE_GL();
@@ -408,6 +412,18 @@
if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
+#if 0 /* Enabling this breaks Tomb Raider 3, need to investigate... */
+ TRACE("Enumerating GL_RGB unpacked (32)\n");
+ pformat->dwFlags = DDPF_RGB;
+ pformat->u1.dwRGBBitCount = 32;
+ pformat->u2.dwRBitMask = 0x00FF0000;
+ pformat->u3.dwGBitMask = 0x0000FF00;
+ pformat->u4.dwBBitMask = 0x000000FF;
+ pformat->u5.dwRGBAlphaBitMask = 0x00000000;
+ if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK;
+ if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK;
+#endif
+
TRACE("Enumerating GL_RGB unpacked (24)\n");
pformat->dwFlags = DDPF_RGB;
pformat->u1.dwRGBBitCount = 24;
@@ -847,7 +835,7 @@
} break;
default:
- FIXME("Unhandled vertex type\n");
+ FIXME("Unhandled vertex type %08x\n", d3dvt);
break;
}
}
@@ -1051,6 +1040,10 @@
BOOLEAN vertex_lighted = FALSE;
IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This;
+ /* This is to prevent 'thread contention' between a thread locking the device and another
+ doing 3D display on it... */
+ EnterCriticalSection(&(This->crit));
+
if (TRACE_ON(ddraw)) {
TRACE(" Vertex format : "); dump_flexible_vertex(d3dvtVertexType);
}
@@ -1232,6 +1225,8 @@
LEAVE_GL();
TRACE("End\n");
+
+ LeaveCriticalSection(&(This->crit));
}
HRESULT WINAPI
@@ -1396,20 +1391,28 @@
}
static GLenum
-convert_min_filter_to_GL(D3DTEXTUREMINFILTER dwState)
+convert_min_filter_to_GL(D3DTEXTUREMINFILTER dwMinState, D3DTEXTUREMIPFILTER dwMipState)
{
GLenum gl_state;
- switch (dwState) {
- case D3DTFN_POINT:
- gl_state = GL_NEAREST;
- break;
- case D3DTFN_LINEAR:
- gl_state = GL_LINEAR;
- break;
- default:
- gl_state = GL_LINEAR;
- break;
+ if (dwMipState == D3DTFP_NONE) {
+ switch (dwMinState) {
+ case D3DTFN_POINT: gl_state = GL_NEAREST; break;
+ case D3DTFN_LINEAR: gl_state = GL_LINEAR; break;
+ default: gl_state = GL_LINEAR; break;
+ }
+ } else if (dwMipState == D3DTFP_POINT) {
+ switch (dwMinState) {
+ case D3DTFN_POINT: gl_state = GL_NEAREST_MIPMAP_NEAREST; break;
+ case D3DTFN_LINEAR: gl_state = GL_LINEAR_MIPMAP_NEAREST; break;
+ default: gl_state = GL_LINEAR_MIPMAP_NEAREST; break;
+ }
+ } else {
+ switch (dwMinState) {
+ case D3DTFN_POINT: gl_state = GL_NEAREST_MIPMAP_LINEAR; break;
+ case D3DTFN_LINEAR: gl_state = GL_LINEAR_MIPMAP_LINEAR; break;
+ default: gl_state = GL_LINEAR_MIPMAP_LINEAR; break;
+ }
}
return gl_state;
}
@@ -1433,6 +1436,73 @@
return gl_state;
}
+/* We need a static function for that to handle the 'special' case of 'SELECT_ARG2' */
+static BOOLEAN
+handle_color_alpha_args(DWORD dwStage, D3DTEXTURESTAGESTATETYPE d3dTexStageStateType, DWORD dwState, D3DTEXTUREOP tex_op)
+{
+ BOOLEAN is_complement = FALSE;
+ BOOLEAN is_alpha_replicate = FALSE;
+ BOOLEAN handled = TRUE;
+ GLenum src;
+ BOOLEAN is_color = ((d3dTexStageStateType == D3DTSS_COLORARG1) || (d3dTexStageStateType == D3DTSS_COLORARG2));
+ int num;
+
+ if (is_color) {
+ if (d3dTexStageStateType == D3DTSS_COLORARG1) num = 0;
+ else if (d3dTexStageStateType == D3DTSS_COLORARG2) num = 1;
+ else {
+ handled = FALSE;
+ num = 0;
+ }
+ if (tex_op == D3DTOP_SELECTARG2) {
+ num = 1 - num;
+ }
+ } else {
+ if (d3dTexStageStateType == D3DTSS_ALPHAARG1) num = 0;
+ else if (d3dTexStageStateType == D3DTSS_ALPHAARG2) num = 1;
+ else {
+ handled = FALSE;
+ num = 0;
+ }
+ if (tex_op == D3DTOP_SELECTARG2) {
+ num = 1 - num;
+ }
+ }
+
+ if (dwState & D3DTA_COMPLEMENT) {
+ is_complement = TRUE;
+ }
+ if (dwState & D3DTA_ALPHAREPLICATE) {
+ is_alpha_replicate = TRUE;
+ }
+ dwState &= D3DTA_SELECTMASK;
+ if ((dwStage == 0) && (dwState == D3DTA_CURRENT)) {
+ dwState = D3DTA_DIFFUSE;
+ }
+
+ switch (dwState) {
+ case D3DTA_CURRENT: src = GL_PREVIOUS_EXT; break;
+ case D3DTA_DIFFUSE: src = GL_PRIMARY_COLOR_ARB; break;
+ case D3DTA_TEXTURE: src = GL_TEXTURE; break;
+ case D3DTA_TFACTOR: src = GL_CONSTANT_ARB; FIXME(" no handling yet of setting of constant value !\n"); break;
+ default: src = GL_TEXTURE; handled = FALSE; break;
+ }
+
+ if (is_color) {
+ glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB + num, src);
+ if (is_alpha_replicate) {
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB + num, is_complement ? GL_ONE_MINUS_SRC_ALPHA : GL_SRC_ALPHA);
+ } else {
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB + num, is_complement ? GL_ONE_MINUS_SRC_COLOR : GL_SRC_COLOR);
+ }
+ } else {
+ glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB + num, src);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB + num, is_complement ? GL_ONE_MINUS_SRC_ALPHA : GL_SRC_ALPHA);
+ }
+
+ return handled;
+}
+
HRESULT WINAPI
GL_IDirect3DDeviceImpl_7_3T_SetTextureStageState(LPDIRECT3DDEVICE7 iface,
DWORD dwStage,
@@ -1440,63 +1510,83 @@
DWORD dwState)
{
ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
+ const char *type;
+ DWORD prev_state;
TRACE("(%p/%p)->(%08lx,%08x,%08lx)\n", This, iface, dwStage, d3dTexStageStateType, dwState);
if (dwStage > 0) return DD_OK; /* We nothing in this case for now */
- if (TRACE_ON(ddraw)) {
- TRACE(" Stage type is : ");
- switch (d3dTexStageStateType) {
-#define GEN_CASE(a) case a: TRACE(#a " "); break
- GEN_CASE(D3DTSS_COLOROP);
- GEN_CASE(D3DTSS_COLORARG1);
- GEN_CASE(D3DTSS_COLORARG2);
- GEN_CASE(D3DTSS_ALPHAOP);
- GEN_CASE(D3DTSS_ALPHAARG1);
- GEN_CASE(D3DTSS_ALPHAARG2);
- GEN_CASE(D3DTSS_BUMPENVMAT00);
- GEN_CASE(D3DTSS_BUMPENVMAT01);
- GEN_CASE(D3DTSS_BUMPENVMAT10);
- GEN_CASE(D3DTSS_BUMPENVMAT11);
- GEN_CASE(D3DTSS_TEXCOORDINDEX);
- GEN_CASE(D3DTSS_ADDRESS);
- GEN_CASE(D3DTSS_ADDRESSU);
- GEN_CASE(D3DTSS_ADDRESSV);
- GEN_CASE(D3DTSS_BORDERCOLOR);
- GEN_CASE(D3DTSS_MAGFILTER);
- GEN_CASE(D3DTSS_MINFILTER);
- GEN_CASE(D3DTSS_MIPFILTER);
- GEN_CASE(D3DTSS_MIPMAPLODBIAS);
- GEN_CASE(D3DTSS_MAXMIPLEVEL);
- GEN_CASE(D3DTSS_MAXANISOTROPY);
- GEN_CASE(D3DTSS_BUMPENVLSCALE);
- GEN_CASE(D3DTSS_BUMPENVLOFFSET);
- GEN_CASE(D3DTSS_TEXTURETRANSFORMFLAGS);
+ switch (d3dTexStageStateType) {
+#define GEN_CASE(a) case a: type = #a; break
+ GEN_CASE(D3DTSS_COLOROP);
+ GEN_CASE(D3DTSS_COLORARG1);
+ GEN_CASE(D3DTSS_COLORARG2);
+ GEN_CASE(D3DTSS_ALPHAOP);
+ GEN_CASE(D3DTSS_ALPHAARG1);
+ GEN_CASE(D3DTSS_ALPHAARG2);
+ GEN_CASE(D3DTSS_BUMPENVMAT00);
+ GEN_CASE(D3DTSS_BUMPENVMAT01);
+ GEN_CASE(D3DTSS_BUMPENVMAT10);
+ GEN_CASE(D3DTSS_BUMPENVMAT11);
+ GEN_CASE(D3DTSS_TEXCOORDINDEX);
+ GEN_CASE(D3DTSS_ADDRESS);
+ GEN_CASE(D3DTSS_ADDRESSU);
+ GEN_CASE(D3DTSS_ADDRESSV);
+ GEN_CASE(D3DTSS_BORDERCOLOR);
+ GEN_CASE(D3DTSS_MAGFILTER);
+ GEN_CASE(D3DTSS_MINFILTER);
+ GEN_CASE(D3DTSS_MIPFILTER);
+ GEN_CASE(D3DTSS_MIPMAPLODBIAS);
+ GEN_CASE(D3DTSS_MAXMIPLEVEL);
+ GEN_CASE(D3DTSS_MAXANISOTROPY);
+ GEN_CASE(D3DTSS_BUMPENVLSCALE);
+ GEN_CASE(D3DTSS_BUMPENVLOFFSET);
+ GEN_CASE(D3DTSS_TEXTURETRANSFORMFLAGS);
#undef GEN_CASE
- default: TRACE("UNKNOWN !!!");
- }
- TRACE(" => ");
+ default: type = "UNKNOWN";
}
+ /* Store the values in the state array */
+ prev_state = This->state_block.texture_stage_state[dwStage][d3dTexStageStateType - 1];
+ This->state_block.texture_stage_state[dwStage][d3dTexStageStateType - 1] = dwState;
+ /* Some special cases when one state modifies more than one... */
+ if (d3dTexStageStateType == D3DTSS_ADDRESS) {
+ This->state_block.texture_stage_state[dwStage][D3DTSS_ADDRESSU - 1] = dwState;
+ This->state_block.texture_stage_state[dwStage][D3DTSS_ADDRESSV - 1] = dwState;
+ }
+
switch (d3dTexStageStateType) {
case D3DTSS_MINFILTER:
+ case D3DTSS_MIPFILTER:
if (TRACE_ON(ddraw)) {
- switch ((D3DTEXTUREMINFILTER) dwState) {
- case D3DTFN_POINT: TRACE("D3DTFN_POINT\n"); break;
- case D3DTFN_LINEAR: TRACE("D3DTFN_LINEAR\n"); break;
- default: TRACE(" state unhandled (%ld).\n", dwState); break;
+ if (d3dTexStageStateType == D3DTSS_MINFILTER) {
+ switch ((D3DTEXTUREMINFILTER) dwState) {
+ case D3DTFN_POINT: TRACE(" Stage type is : D3DTSS_MINFILTER => D3DTFN_POINT\n"); break;
+ case D3DTFN_LINEAR: TRACE(" Stage type is : D3DTSS_MINFILTER => D3DTFN_LINEAR\n"); break;
+ default: FIXME(" Unhandled stage type : D3DTSS_MINFILTER => %08lx\n", dwState); break;
+ }
+ } else {
+ switch ((D3DTEXTUREMIPFILTER) dwState) {
+ case D3DTFP_NONE: TRACE(" Stage type is : D3DTSS_MIPFILTER => D3DTFP_NONE\n"); break;
+ case D3DTFP_POINT: TRACE(" Stage type is : D3DTSS_MIPFILTER => D3DTFP_POINT\n"); break;
+ case D3DTFP_LINEAR: TRACE(" Stage type is : D3DTSS_MIPFILTER => D3DTFP_LINEAR\n"); break;
+ default: FIXME(" Unhandled stage type : D3DTSS_MIPFILTER => %08lx\n", dwState); break;
+ }
}
}
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, convert_min_filter_to_GL(dwState));
- break;
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+ convert_min_filter_to_GL(This->state_block.texture_stage_state[dwStage][D3DTSS_MINFILTER - 1],
+ This->state_block.texture_stage_state[dwStage][D3DTSS_MIPFILTER - 1]));
+ break;
case D3DTSS_MAGFILTER:
if (TRACE_ON(ddraw)) {
switch ((D3DTEXTUREMAGFILTER) dwState) {
- case D3DTFG_POINT: TRACE("D3DTFN_POINT\n"); break;
- case D3DTFG_LINEAR: TRACE("D3DTFN_LINEAR\n"); break;
- default: TRACE(" state unhandled (%ld).\n", dwState); break;
+ case D3DTFG_POINT: TRACE(" Stage type is : D3DTSS_MAGFILTER => D3DTFN_POINT\n"); break;
+ case D3DTFG_LINEAR: TRACE(" Stage type is : D3DTSS_MAGFILTER => D3DTFN_LINEAR\n"); break;
+ default: FIXME(" Unhandled stage type : D3DTSS_MAGFILTER => %08lx\n", dwState); break;
}
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, convert_mag_filter_to_GL(dwState));
@@ -1507,10 +1597,15 @@
case D3DTSS_ADDRESSV: {
GLenum arg = GL_REPEAT; /* Default value */
switch ((D3DTEXTUREADDRESS) dwState) {
- case D3DTADDRESS_WRAP: if (TRACE_ON(ddraw)) TRACE("D3DTADDRESS_WRAP\n"); arg = GL_REPEAT; break;
- case D3DTADDRESS_CLAMP: if (TRACE_ON(ddraw)) TRACE("D3DTADDRESS_CLAMP\n"); arg = GL_CLAMP; break;
- case D3DTADDRESS_BORDER: if (TRACE_ON(ddraw)) TRACE("D3DTADDRESS_BORDER\n"); arg = GL_CLAMP_TO_EDGE; break;
- default: TRACE(" state unhandled (%ld).\n", dwState);
+ case D3DTADDRESS_WRAP: TRACE(" Stage type is : %s => D3DTADDRESS_WRAP\n", type); arg = GL_REPEAT; break;
+ case D3DTADDRESS_CLAMP: TRACE(" Stage type is : %s => D3DTADDRESS_CLAMP\n", type); arg = GL_CLAMP; break;
+ case D3DTADDRESS_BORDER: TRACE(" Stage type is : %s => D3DTADDRESS_BORDER\n", type); arg = GL_CLAMP_TO_EDGE; break;
+#if defined(GL_VERSION_1_4)
+ case D3DTADDRESS_MIRROR: TRACE(" Stage type is : %s => D3DTADDRESS_MIRROR\n", type); arg = GL_MIRRORED_REPEAT; break;
+#elif defined(GL_ARB_texture_mirrored_repeat)
+ case D3DTADDRESS_MIRROR: TRACE(" Stage type is : %s => D3DTADDRESS_MIRROR\n", type); arg = GL_MIRRORED_REPEAT_ARB; break;
+#endif
+ default: FIXME(" Unhandled stage type : %s => %08lx\n", type, dwState); break;
}
if ((d3dTexStageStateType == D3DTSS_ADDRESS) ||
(d3dTexStageStateType == D3DTSS_ADDRESSU))
@@ -1519,18 +1614,174 @@
(d3dTexStageStateType == D3DTSS_ADDRESSV))
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, arg);
} break;
+
+ case D3DTSS_ALPHAOP:
+ case D3DTSS_COLOROP: {
+ int scale = 1;
+ GLenum parm = (d3dTexStageStateType == D3DTSS_ALPHAOP) ? GL_COMBINE_ALPHA_ARB : GL_COMBINE_RGB_ARB;
+ const char *value;
+ int handled = 1;
+
+ switch (dwState) {
+#define GEN_CASE(a) case a: value = #a; break
+ GEN_CASE(D3DTOP_DISABLE);
+ GEN_CASE(D3DTOP_SELECTARG1);
+ GEN_CASE(D3DTOP_SELECTARG2);
+ GEN_CASE(D3DTOP_MODULATE);
+ GEN_CASE(D3DTOP_MODULATE2X);
+ GEN_CASE(D3DTOP_MODULATE4X);
+ GEN_CASE(D3DTOP_ADD);
+ GEN_CASE(D3DTOP_ADDSIGNED);
+ GEN_CASE(D3DTOP_ADDSIGNED2X);
+ GEN_CASE(D3DTOP_SUBTRACT);
+ GEN_CASE(D3DTOP_ADDSMOOTH);
+ GEN_CASE(D3DTOP_BLENDDIFFUSEALPHA);
+ GEN_CASE(D3DTOP_BLENDTEXTUREALPHA);
+ GEN_CASE(D3DTOP_BLENDFACTORALPHA);
+ GEN_CASE(D3DTOP_BLENDTEXTUREALPHAPM);
+ GEN_CASE(D3DTOP_BLENDCURRENTALPHA);
+ GEN_CASE(D3DTOP_PREMODULATE);
+ GEN_CASE(D3DTOP_MODULATEALPHA_ADDCOLOR);
+ GEN_CASE(D3DTOP_MODULATECOLOR_ADDALPHA);
+ GEN_CASE(D3DTOP_MODULATEINVALPHA_ADDCOLOR);
+ GEN_CASE(D3DTOP_MODULATEINVCOLOR_ADDALPHA);
+ GEN_CASE(D3DTOP_BUMPENVMAP);
+ GEN_CASE(D3DTOP_BUMPENVMAPLUMINANCE);
+ GEN_CASE(D3DTOP_DOTPRODUCT3);
+ GEN_CASE(D3DTOP_FORCE_DWORD);
+#undef GEN_CASE
+ default: value = "UNKNOWN";
+ }
+
+ if ((d3dTexStageStateType == D3DTSS_COLOROP) && (dwState == D3DTOP_DISABLE) && (dwStage == 0)) {
+ glDisable(GL_TEXTURE_2D);
+ TRACE(" disabling 2D texturing.\n");
+ } else {
+ /* Re-enable texturing */
+ if ((dwStage == 0) && (This->current_texture[0] != NULL)) {
+ glEnable(GL_TEXTURE_2D);
+ TRACE(" enabling 2D texturing.\n");
+ }
+
+ /* Re-Enable GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB */
+ if (dwState != D3DTOP_DISABLE) {
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
+ }
+
+ /* Now set up the operand correctly */
+ switch (dwState) {
+ case D3DTOP_DISABLE:
+ /* Contrary to the docs, alpha can be disabled when colorop is enabled
+ and it works, so ignore this op */
+ TRACE(" Note : disable ALPHAOP but COLOROP enabled!\n");
+ break;
+
+ case D3DTOP_SELECTARG1:
+ case D3DTOP_SELECTARG2:
+ glTexEnvi(GL_TEXTURE_ENV, parm, GL_REPLACE);
+ break;
+
+ case D3DTOP_MODULATE4X:
+ scale = scale * 2; /* Drop through */
+ case D3DTOP_MODULATE2X:
+ scale = scale * 2; /* Drop through */
+ case D3DTOP_MODULATE:
+ glTexEnvi(GL_TEXTURE_ENV, parm, GL_MODULATE);
+ break;
+
+ case D3DTOP_ADD:
+ glTexEnvi(GL_TEXTURE_ENV, parm, GL_ADD);
+ break;
+
+ case D3DTOP_ADDSIGNED2X:
+ scale = scale * 2; /* Drop through */
+ case D3DTOP_ADDSIGNED:
+ glTexEnvi(GL_TEXTURE_ENV, parm, GL_ADD_SIGNED_ARB);
+ break;
+
+ default:
+ handled = FALSE;
+ break;
+ }
+ }
+
+ if (((prev_state == D3DTOP_SELECTARG2) && (dwState != D3DTOP_SELECTARG2)) ||
+ ((dwState == D3DTOP_SELECTARG2) && (prev_state != D3DTOP_SELECTARG2))) {
+ /* Switch the arguments if needed... */
+ if (d3dTexStageStateType == D3DTSS_COLOROP) {
+ handle_color_alpha_args(dwStage, D3DTSS_COLORARG1,
+ This->state_block.texture_stage_state[dwStage][D3DTSS_COLORARG1 - 1],
+ dwState);
+ handle_color_alpha_args(dwStage, D3DTSS_COLORARG2,
+ This->state_block.texture_stage_state[dwStage][D3DTSS_COLORARG2 - 1],
+ dwState);
+ } else {
+ handle_color_alpha_args(dwStage, D3DTSS_ALPHAARG1,
+ This->state_block.texture_stage_state[dwStage][D3DTSS_ALPHAARG1 - 1],
+ dwState);
+ handle_color_alpha_args(dwStage, D3DTSS_ALPHAARG2,
+ This->state_block.texture_stage_state[dwStage][D3DTSS_ALPHAARG2 - 1],
+ dwState);
+ }
+ }
+
+ if (handled) {
+ if (d3dTexStageStateType == D3DTSS_ALPHAOP) {
+ glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, scale);
+ } else {
+ glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, scale);
+ }
+ TRACE(" Stage type is : %s => %s\n", type, value);
+ } else {
+ FIXME(" Unhandled stage type is : %s => %s\n", type, value);
+ }
+ } break;
+
+ case D3DTSS_COLORARG1:
+ case D3DTSS_COLORARG2:
+ case D3DTSS_ALPHAARG1:
+ case D3DTSS_ALPHAARG2: {
+ const char *value, *value_comp = "", *value_alpha = "";
+ BOOLEAN handled;
+ D3DTEXTUREOP tex_op;
+
+ switch (dwState & D3DTA_SELECTMASK) {
+#define GEN_CASE(a) case a: value = #a; break
+ GEN_CASE(D3DTA_DIFFUSE);
+ GEN_CASE(D3DTA_CURRENT);
+ GEN_CASE(D3DTA_TEXTURE);
+ GEN_CASE(D3DTA_TFACTOR);
+ GEN_CASE(D3DTA_SPECULAR);
+#undef GEN_CASE
+ default: value = "UNKNOWN";
+ }
+ if (dwState & D3DTA_COMPLEMENT) {
+ value_comp = " | D3DTA_COMPLEMENT";
+ }
+ if (dwState & D3DTA_ALPHAREPLICATE) {
+ value_alpha = " | D3DTA_ALPHAREPLICATE";
+ }
+
+ if ((d3dTexStageStateType == D3DTSS_COLORARG1) || (d3dTexStageStateType == D3DTSS_COLORARG2)) {
+ tex_op = This->state_block.texture_stage_state[dwStage][D3DTSS_COLOROP - 1];
+ } else {
+ tex_op = This->state_block.texture_stage_state[dwStage][D3DTSS_ALPHAOP - 1];
+ }
+
+ handled = handle_color_alpha_args(dwStage, d3dTexStageStateType, dwState, tex_op);
+
+ if (handled) {
+ TRACE(" Stage type : %s => %s%s%s\n", type, value, value_comp, value_alpha);
+ } else {
+ FIXME(" Unhandled stage type : %s => %s%s%s\n", type, value, value_comp, value_alpha);
+ }
+ } break;
default:
- if (TRACE_ON(ddraw)) TRACE(" unhandled.\n");
+ FIXME(" Unhandled stage type : %s => %08lx\n", type, dwState);
+ break;
}
- This->state_block.texture_stage_state[dwStage][d3dTexStageStateType - 1] = dwState;
- /* Some special cases when one state modifies more than one... */
- if (d3dTexStageStateType == D3DTSS_ADDRESS) {
- This->state_block.texture_stage_state[dwStage][D3DTSS_ADDRESSU - 1] = dwState;
- This->state_block.texture_stage_state[dwStage][D3DTSS_ADDRESSV - 1] = dwState;
- }
-
return DD_OK;
}
@@ -1558,17 +1809,30 @@
glDisable(GL_TEXTURE_2D);
} else {
IDirectDrawSurfaceImpl *tex_impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, lpTexture2);
+ GLint max_mip_level;
This->current_texture[dwStage] = tex_impl;
IDirectDrawSurface7_AddRef(ICOM_INTERFACE(tex_impl, IDirectDrawSurface7)); /* Not sure about this either */
-
- glEnable(GL_TEXTURE_2D);
+
+ if (This->state_block.texture_stage_state[dwStage][D3DTSS_COLOROP - 1] != D3DTOP_DISABLE) {
+ /* Do not re-enable texturing if it was disabled due to the COLOROP code */
+ glEnable(GL_TEXTURE_2D);
+ TRACE(" enabling 2D texturing.\n");
+ }
gltex_upload_texture(tex_impl);
+ if ((tex_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) == 0) {
+ max_mip_level = 0;
+ } else {
+ max_mip_level = tex_impl->surface_desc.u2.dwMipMapCount - 1;
+ }
+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
convert_mag_filter_to_GL(This->state_block.texture_stage_state[dwStage][D3DTSS_MAGFILTER - 1]));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
- convert_min_filter_to_GL(This->state_block.texture_stage_state[dwStage][D3DTSS_MINFILTER - 1]));
+ convert_min_filter_to_GL(This->state_block.texture_stage_state[dwStage][D3DTSS_MINFILTER - 1],
+ This->state_block.texture_stage_state[dwStage][D3DTSS_MIPFILTER - 1]));
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, max_mip_level);
}
LEAVE_GL();
@@ -2137,18 +2401,22 @@
*/
static void d3ddevice_lock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags)
{
- /* First, check if we need to do anything */
+ /* Try to acquire the device critical section */
+ EnterCriticalSection(&(This->d3ddevice->crit));
+
+ /* Then check if we need to do anything */
if ((This->lastlocktype & DDLOCK_WRITEONLY) == 0) {
GLenum buffer_type;
GLenum prev_read;
RECT loc_rect;
+ WARN(" application does a lock on a 3D surface - expect slow downs.\n");
+
ENTER_GL();
glGetIntegerv(GL_READ_BUFFER, &prev_read);
glFlush();
- WARN(" application does a lock on a 3D surface - expect slow downs.\n");
if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0) {
/* Application wants to lock the front buffer */
glReadBuffer(GL_FRONT);
@@ -2174,10 +2442,12 @@
} else {
loc_rect = *pRect;
}
+#if 0
glReadPixels(loc_rect.left, loc_rect.top, loc_rect.right, loc_rect.bottom,
GL_RGB, buffer_type, ((char *)This->surface_desc.lpSurface
+ loc_rect.top * This->surface_desc.u1.lPitch
+ loc_rect.left * GET_BPP(This->surface_desc)));
+#endif
glReadBuffer(prev_read);
LEAVE_GL();
}
@@ -2190,11 +2460,12 @@
GLenum buffer_type;
GLenum prev_draw;
+ WARN(" application does an unlock on a 3D surface - expect slow downs.\n");
+
ENTER_GL();
glGetIntegerv(GL_DRAW_BUFFER, &prev_draw);
- WARN(" application does an unlock on a 3D surface - expect slow downs.\n");
if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0) {
/* Application wants to lock the front buffer */
glDrawBuffer(GL_FRONT);
@@ -2210,17 +2481,41 @@
} else {
WARN(" unsupported pixel format.\n");
LEAVE_GL();
+
+ /* And 'frees' the device critical section */
+ LeaveCriticalSection(&(This->d3ddevice->crit));
return;
}
glRasterPos2f(0.0, 0.0);
+#if 0
glDrawPixels(This->surface_desc.dwWidth, This->surface_desc.dwHeight,
GL_RGB, buffer_type, This->surface_desc.lpSurface);
+#endif
glDrawBuffer(prev_draw);
LEAVE_GL();
}
+
+ /* And 'frees' the device critical section */
+ LeaveCriticalSection(&(This->d3ddevice->crit));
}
+static void
+apply_texture_state(IDirect3DDeviceImpl *This)
+{
+ int stage, state;
+
+ /* Initialize texture stages states */
+ for (stage = 0; stage < MAX_TEXTURES; stage++) {
+ for (state = 0; state < HIGHEST_TEXTURE_STAGE_STATE; state += 1) {
+ if (This->state_block.set_flags.texture_stage_state[stage][state] == TRUE) {
+ IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7),
+ stage, state + 1, This->state_block.texture_stage_state[stage][state]);
+ }
+ }
+ }
+}
+
HRESULT
d3ddevice_create(IDirect3DDeviceImpl **obj, IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *surface)
{
@@ -2248,6 +2543,8 @@
object->set_matrices = d3ddevice_set_matrices;
object->matrices_updated = d3ddevice_matrices_updated;
+ InitializeCriticalSection(&(object->crit));
+
TRACE(" creating OpenGL device for surface = %p, d3d = %p\n", surface, d3d);
device_context = GetDC(surface->ddraw_owner->window);
@@ -2295,18 +2592,26 @@
buffer = GL_FRONT;
}
- for (surf = surface; surf->prev_attached != NULL; surf = surf->prev_attached) ;
- for (; surf != NULL; surf = surf->next_attached) {
- if (((surf->surface_desc.ddsCaps.dwCaps & (DDSCAPS_3DDEVICE)) == (DDSCAPS_3DDEVICE)) &&
- ((surf->surface_desc.ddsCaps.dwCaps & (DDSCAPS_ZBUFFER)) != (DDSCAPS_ZBUFFER))) {
- /* Override the Lock / Unlock function for all these surfaces */
- surf->lock_update = d3ddevice_lock_update;
- surf->unlock_update = d3ddevice_unlock_update;
- /* And install also the blt / bltfast overrides */
- surf->aux_blt = d3ddevice_blt;
- surf->aux_bltfast = d3ddevice_bltfast;
+ for (surf = surface; surf != NULL; surf = surf->surface_owner) {
+ IDirectDrawSurfaceImpl *surf2;
+ for (surf2 = surf; surf2->prev_attached != NULL; surf2 = surf2->prev_attached) ;
+ for (; surf2 != NULL; surf2 = surf2->next_attached) {
+ TRACE(" checking surface %p :", surf2);
+ if (((surf2->surface_desc.ddsCaps.dwCaps & (DDSCAPS_3DDEVICE)) == (DDSCAPS_3DDEVICE)) &&
+ ((surf2->surface_desc.ddsCaps.dwCaps & (DDSCAPS_ZBUFFER)) != (DDSCAPS_ZBUFFER))) {
+ /* Override the Lock / Unlock function for all these surfaces */
+ surf2->lock_update = d3ddevice_lock_update;
+ surf2->unlock_update = d3ddevice_unlock_update;
+ /* And install also the blt / bltfast overrides */
+ surf2->aux_blt = d3ddevice_blt;
+ surf2->aux_bltfast = d3ddevice_bltfast;
+
+ TRACE(" overiding direct surface access.\n");
+ } else {
+ TRACE(" no overide.\n");
+ }
+ surf2->d3ddevice = object;
}
- surf->d3ddevice = object;
}
/* Set the various light parameters */
@@ -2369,9 +2672,9 @@
/* FIXME: Should handle other versions than just 7 */
InitDefaultStateBlock(&object->state_block, 7);
- /* Apply default render state values */
+ /* Apply default render state and texture stage state values */
apply_render_state(object, &object->state_block);
- /* FIXME: do something similar for ligh_state and texture_stage_state */
+ apply_texture_state(object);
/* And fill the fog table with the default fog value */
build_fog_table(gl_object->fog_table, object->state_block.render_state[D3DRENDERSTATE_FOGCOLOR - 1]);
More information about the wine-patches
mailing list