From 21856fbd1cfe6cd473d464de85648f564ea99aa1 Mon Sep 17 00:00:00 2001 From: Lionel Ulmer Date: Wed, 4 Jun 2003 23:10:38 +0000 Subject: [PATCH] - implement FB => Texture blits - fix compilation on non-recent glext.h systems --- dlls/ddraw/d3ddevice/mesa.c | 2 +- dlls/ddraw/d3dtexture.c | 1039 +++++++++++++++++++++++++------------------ dlls/ddraw/gl_api.h | 1 + dlls/ddraw/gl_private.h | 1 + dlls/ddraw/mesa_private.h | 14 +- 5 files changed, 604 insertions(+), 453 deletions(-) diff --git a/dlls/ddraw/d3ddevice/mesa.c b/dlls/ddraw/d3ddevice/mesa.c index 5fbf30a7aca..3880e282b92 100644 --- a/dlls/ddraw/d3ddevice/mesa.c +++ b/dlls/ddraw/d3ddevice/mesa.c @@ -1824,7 +1824,7 @@ GL_IDirect3DDeviceImpl_7_3T_SetTextureStageState(LPDIRECT3DDEVICE7 iface, case D3DTOP_BLENDCURRENTALPHA: src = GL_PREVIOUS_EXT; } - glTexEnvi(GL_TEXTURE_ENV, parm, GL_INTERPOLATE_ARB); + glTexEnvi(GL_TEXTURE_ENV, parm, GL_INTERPOLATE_EXT); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, src); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_ALPHA); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_EXT, src); diff --git a/dlls/ddraw/d3dtexture.c b/dlls/ddraw/d3dtexture.c index 51fc54c0590..7327b32045b 100644 --- a/dlls/ddraw/d3dtexture.c +++ b/dlls/ddraw/d3dtexture.c @@ -82,509 +82,529 @@ get_sub_mimaplevel(IDirectDrawSurfaceImpl *tex_ptr) /******************************************************************************* * IDirectSurface callback methods */ + HRESULT -gltex_upload_texture(IDirectDrawSurfaceImpl *This) { - IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private; +gltex_flush_texture_memory_to_GL(IDirectDrawSurfaceImpl *surf_ptr) { #if 0 static BOOL color_table_queried = FALSE; #endif 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; - - TRACE(" activating OpenGL texture id %d.\n", tex_name); - glBindTexture(GL_TEXTURE_2D, tex_name); - - 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 internal_format = GL_RGBA, 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; + GLenum internal_format = GL_RGBA, 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 (gl_surf_ptr->dirty_flag == FALSE) { - TRACE(" - level %d already uploaded.\n", surf_ptr->mipmap_level); - } else { - TRACE(" - uploading texture level %d (initial done = %d).\n", - surf_ptr->mipmap_level, gl_surf_ptr->initial_upload_done); - - /* 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; - + if (gl_surf_ptr->dirty_flag != SURFACE_MEMORY_DIRTY) { + TRACE(" - level %d already uploaded.\n", surf_ptr->mipmap_level); + } else { + TRACE(" - uploading texture level %d (initial done = %d).\n", + surf_ptr->mipmap_level, gl_surf_ptr->initial_upload_done); + + /* 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; + #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; - } + if (color_table_queried == FALSE) { + ptr_ColorTableEXT = + ((Mesa_DeviceCapabilities *) ((x11_dd_private *) surf_ptr->surface->s.ddraw->d->private)->device_capabilities)->ptr_ColorTableEXT; + } #endif - - 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 { - /* 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; - } + + 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 { + /* 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; } + } - 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 { - DWORD i; - BYTE *src = (BYTE *) src_d->lpSurface, *dst; - - if (glThis->surface_ptr != NULL) - surface = glThis->surface_ptr; - else - 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; - internal_format = GL_RGBA; - pixel_format = GL_UNSIGNED_BYTE; + 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 { + DWORD i; + BYTE *src = (BYTE *) src_d->lpSurface, *dst; + + if (gl_surf_ptr->surface_ptr != NULL) + surface = gl_surf_ptr->surface_ptr; + else + 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]; } - } 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; - internal_format = GL_RGB; - pixel_format = GL_UNSIGNED_BYTE_3_3_2; - } - } else { + + format = GL_RGBA; + internal_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; + internal_format = GL_RGB; + pixel_format = GL_UNSIGNED_BYTE_3_3_2; } - } 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. + } 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; - - if (glThis->surface_ptr != NULL) - surface = glThis->surface_ptr; - else - surface = 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; - internal_format = GL_RGBA; - pixel_format = GL_UNSIGNED_SHORT_5_5_5_1; - } else { - format = GL_RGB; - internal_format = GL_RGB; - pixel_format = GL_UNSIGNED_SHORT_5_6_5; + 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; + + if (gl_surf_ptr->surface_ptr != NULL) + surface = gl_surf_ptr->surface_ptr; + else + surface = 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++; } - } 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; + + format = GL_RGBA; internal_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; - - if (glThis->surface_ptr != NULL) - surface = glThis->surface_ptr; - else - surface = 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; - internal_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; - - if (glThis->surface_ptr != NULL) - surface = glThis->surface_ptr; - else - surface = 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 { + format = GL_RGB; + internal_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; + internal_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; + + if (gl_surf_ptr->surface_ptr != NULL) + surface = gl_surf_ptr->surface_ptr; + else + surface = 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 == 0x0F00) && - (src_d->ddpfPixelFormat.u3.dwGBitMask == 0x00F0) && - (src_d->ddpfPixelFormat.u4.dwBBitMask == 0x000F) && - (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0xF000)) { - /* Move the four Alpha bits... */ - if (src_d->dwFlags & DDSD_CKSRCBLT) { - DWORD i; - WORD *src = (WORD *) src_d->lpSurface, *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; + internal_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; - if (glThis->surface_ptr != NULL) - surface = glThis->surface_ptr; - else - surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - src_d->dwWidth * src_d->dwHeight * sizeof(WORD)); - dst = surface; - - 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++; - } - format = GL_RGBA; - internal_format = GL_RGBA; - pixel_format = GL_UNSIGNED_SHORT_4_4_4_4; - } else { - format = GL_BGRA; - internal_format = GL_RGBA; - pixel_format = GL_UNSIGNED_SHORT_4_4_4_4_REV; + if (gl_surf_ptr->surface_ptr != NULL) + surface = gl_surf_ptr->surface_ptr; + else + surface = 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 == 0x7C00) && - (src_d->ddpfPixelFormat.u3.dwGBitMask == 0x03E0) && - (src_d->ddpfPixelFormat.u4.dwBBitMask == 0x001F) && - (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x8000)) { - if (src_d->dwFlags & DDSD_CKSRCBLT) { - DWORD i; - WORD *src = (WORD *) src_d->lpSurface, *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... */ + if (src_d->dwFlags & DDSD_CKSRCBLT) { + DWORD i; + WORD *src = (WORD *) src_d->lpSurface, *dst; - if (glThis->surface_ptr != NULL) - surface = glThis->surface_ptr; - else - surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - src_d->dwWidth * src_d->dwHeight * sizeof(WORD)); - dst = (WORD *) surface; + if (gl_surf_ptr->surface_ptr != NULL) + surface = gl_surf_ptr->surface_ptr; + else + surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + src_d->dwWidth * src_d->dwHeight * sizeof(WORD)); + dst = surface; - 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++; - } - format = GL_RGBA; - internal_format = GL_RGBA; - pixel_format = GL_UNSIGNED_SHORT_5_5_5_1; - } else { - format = GL_BGRA; - internal_format = GL_RGBA; - pixel_format = GL_UNSIGNED_SHORT_1_5_5_5_REV; + 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 if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0x7C00) && - (src_d->ddpfPixelFormat.u3.dwGBitMask == 0x03E0) && - (src_d->ddpfPixelFormat.u4.dwBBitMask == 0x001F) && - (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0000)) { - /* Converting the 0555 format in 5551 packed */ - DWORD i; + format = GL_RGBA; + internal_format = GL_RGBA; + pixel_format = GL_UNSIGNED_SHORT_4_4_4_4; + } else { + format = GL_BGRA; + internal_format = GL_RGBA; + pixel_format = GL_UNSIGNED_SHORT_4_4_4_4_REV; + } + } 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)) { + if (src_d->dwFlags & DDSD_CKSRCBLT) { + DWORD i; WORD *src = (WORD *) src_d->lpSurface, *dst; - if (glThis->surface_ptr != NULL) - surface = glThis->surface_ptr; + if (gl_surf_ptr->surface_ptr != NULL) + surface = gl_surf_ptr->surface_ptr; else surface = 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 |= 0x0001; - dst++; - } - } else { - for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) { - WORD color = *src++; - *dst++ = ((color & 0x7FFF) << 1) | 0x0001; - } + 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++; } - format = GL_RGBA; internal_format = GL_RGBA; pixel_format = GL_UNSIGNED_SHORT_5_5_5_1; } else { - error = TRUE; + format = GL_BGRA; + internal_format = GL_RGBA; + pixel_format = GL_UNSIGNED_SHORT_1_5_5_5_REV; } - } 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; - - if (glThis->surface_ptr != NULL) - surface = glThis->surface_ptr; - else - surface = 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; - internal_format = GL_RGBA; - pixel_format = GL_UNSIGNED_INT_8_8_8_8; - } else { - format = GL_BGR; - internal_format = GL_RGB; - pixel_format = GL_UNSIGNED_BYTE; + } 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 == 0x0000)) { + /* Converting the 0555 format in 5551 packed */ + DWORD i; + WORD *src = (WORD *) src_d->lpSurface, *dst; + + if (gl_surf_ptr->surface_ptr != NULL) + surface = gl_surf_ptr->surface_ptr; + else + surface = 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 |= 0x0001; + dst++; } } else { - error = TRUE; + for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) { + WORD color = *src++; + *dst++ = ((color & 0x7FFF) << 1) | 0x0001; + } } - } 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; - - if (glThis->surface_ptr != NULL) - surface = glThis->surface_ptr; - else - surface = 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; + internal_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; + + if (gl_surf_ptr->surface_ptr != NULL) + surface = gl_surf_ptr->surface_ptr; + else + surface = 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; internal_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)) { - if (src_d->dwFlags & DDSD_CKSRCBLT) { - DWORD i; - DWORD *src = (DWORD *) src_d->lpSurface, *dst; - - if (glThis->surface_ptr != NULL) - surface = glThis->surface_ptr; - else - surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(DWORD)); + } else { + format = GL_BGR; + internal_format = GL_RGB; + 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; - dst = (DWORD *) surface; - 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++; - } - format = GL_RGBA; - internal_format = GL_RGBA; - pixel_format = GL_UNSIGNED_INT_8_8_8_8; - } else { - format = GL_BGRA; - internal_format = GL_RGBA; - pixel_format = GL_UNSIGNED_INT_8_8_8_8_REV; + if (gl_surf_ptr->surface_ptr != NULL) + surface = gl_surf_ptr->surface_ptr; + else + surface = 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++; } - } 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; + } + format = GL_RGBA; + internal_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)) { + if (src_d->dwFlags & DDSD_CKSRCBLT) { + DWORD i; DWORD *src = (DWORD *) src_d->lpSurface, *dst; - if (glThis->surface_ptr != NULL) - surface = glThis->surface_ptr; + if (gl_surf_ptr->surface_ptr != NULL) + surface = gl_surf_ptr->surface_ptr; else surface = 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; - } + dst = (DWORD *) surface; + 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++; } format = GL_RGBA; internal_format = GL_RGBA; pixel_format = GL_UNSIGNED_INT_8_8_8_8; } else { - error = TRUE; + format = GL_BGRA; + internal_format = GL_RGBA; + pixel_format = GL_UNSIGNED_INT_8_8_8_8_REV; } + } 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; + + if (gl_surf_ptr->surface_ptr != NULL) + surface = gl_surf_ptr->surface_ptr; + else + surface = 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; + internal_format = GL_RGBA; + pixel_format = GL_UNSIGNED_INT_8_8_8_8; } else { error = TRUE; } } else { - error = TRUE; - } + error = TRUE; + } + } else { + error = TRUE; + } + + if ((upload_done == FALSE) && (error == FALSE)) { + if (gl_surf_ptr->initial_upload_done == FALSE) { + glTexImage2D(GL_TEXTURE_2D, + surf_ptr->mipmap_level, + internal_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 { + 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); + } + gl_surf_ptr->dirty_flag = SURFACE_MEMORY; - if ((upload_done == FALSE) && (error == FALSE)) { - if (gl_surf_ptr->initial_upload_done == FALSE) { - glTexImage2D(GL_TEXTURE_2D, - surf_ptr->mipmap_level, - internal_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 { - 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); - } - gl_surf_ptr->dirty_flag = FALSE; - - /* And store the surface pointer for future reuse.. */ - if (surface) - glThis->surface_ptr = surface; - } else if (error == TRUE) { - if (ERR_ON(ddraw)) { - ERR(" unsupported pixel format for textures : \n"); - DDRAW_dump_pixelformat(&src_d->ddpfPixelFormat); - } + /* And store the surface pointer for future reuse.. */ + if (surface) + gl_surf_ptr->surface_ptr = surface; + } else if (error == TRUE) { + if (ERR_ON(ddraw)) { + ERR(" unsupported pixel format for textures : \n"); + DDRAW_dump_pixelformat(&src_d->ddpfPixelFormat); } } + } + + return DD_OK; +} + +HRESULT +gltex_flush_texture_GL_to_memory(IDirectDrawSurfaceImpl *surf_ptr) { + IDirect3DTextureGLImpl *gl_surf_ptr = (IDirect3DTextureGLImpl *) surf_ptr->tex_private; + + FIXME("This is not supported yet... Expect some graphical glitches !!!\n"); + + /* GL and memory are in sync again ... */ + gl_surf_ptr->dirty_flag = SURFACE_MEMORY; + + return DD_OK; +} + +HRESULT +gltex_upload_texture(IDirectDrawSurfaceImpl *This) { + IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private; + IDirectDrawSurfaceImpl *surf_ptr; + GLuint tex_name = glThis->tex_name; + + TRACE(" activating OpenGL texture id %d.\n", tex_name); + glBindTexture(GL_TEXTURE_2D, tex_name); + 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) { + gltex_flush_texture_memory_to_GL(surf_ptr); + if (surf_ptr->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) { surf_ptr = get_sub_mimaplevel(surf_ptr); } else { @@ -610,12 +630,124 @@ gltex_setcolorkey_cb(IDirectDrawSurfaceImpl *This, DWORD dwFlags, LPDDCOLORKEY c { IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private; - glThis->dirty_flag = TRUE; + if (glThis->dirty_flag == SURFACE_GL) { + GLuint cur_tex; + + ENTER_GL(); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &cur_tex); + glBindTexture(GL_TEXTURE_2D, glThis->tex_name); + gltex_flush_texture_GL_to_memory(This); + glBindTexture(GL_TEXTURE_2D, cur_tex); + LEAVE_GL(); + } + + glThis->dirty_flag = SURFACE_MEMORY_DIRTY; /* TODO: check color-keying on mipmapped surfaces... */ return DD_OK; } +HRESULT +gltex_blt(IDirectDrawSurfaceImpl *This, LPRECT rdst, + LPDIRECTDRAWSURFACE7 src, LPRECT rsrc, + DWORD dwFlags, LPDDBLTFX lpbltfx) +{ + if (src != NULL) { + IDirectDrawSurfaceImpl *src_ptr = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, src); + if (src_ptr->surface_desc.ddsCaps.dwCaps & DDSCAPS_3DDEVICE) { + FIXME("Blt from framebuffer to texture - unsupported now, please report !\n"); + } + } + return DDERR_INVALIDPARAMS; +} + +HRESULT +gltex_bltfast(IDirectDrawSurfaceImpl *surf_ptr, DWORD dstx, + DWORD dsty, LPDIRECTDRAWSURFACE7 src, + LPRECT rsrc, DWORD trans) +{ + if (src != NULL) { + IDirectDrawSurfaceImpl *src_ptr = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, src); + + if ((src_ptr->surface_desc.ddsCaps.dwCaps & DDSCAPS_3DDEVICE) && + ((trans & (DDBLTFAST_SRCCOLORKEY | DDBLTFAST_DESTCOLORKEY)) == 0)) { + /* This is a blt without color keying... We can use the direct copy. */ + RECT rsrc2; + DWORD width, height; + GLuint cur_tex; + IDirect3DTextureGLImpl *gl_surf_ptr = surf_ptr->tex_private; + int y; + + if (rsrc == NULL) { + WARN("rsrc is NULL\n"); + rsrc = &rsrc2; + + rsrc->left = 0; + rsrc->top = 0; + rsrc->right = src_ptr->surface_desc.dwWidth; + rsrc->bottom = src_ptr->surface_desc.dwHeight; + } + + width = rsrc->right - rsrc->left; + height = rsrc->bottom - rsrc->top; + + if (((dstx + width) > surf_ptr->surface_desc.dwWidth) || + ((dsty + height) > surf_ptr->surface_desc.dwHeight)) { + FIXME("Does not handle clipping yet in FB => Texture blits !\n"); + return DDERR_INVALIDPARAMS; + } + + TRACE(" direct frame buffer => texture BltFast override.\n"); + + ENTER_GL(); + + glGetIntegerv(GL_TEXTURE_BINDING_2D, &cur_tex); + glBindTexture(GL_TEXTURE_2D, gl_surf_ptr->tex_name); + + if ((gl_surf_ptr->dirty_flag == SURFACE_MEMORY_DIRTY) && + !((dstx == 0) && (dsty == 0) && + (width == surf_ptr->surface_desc.dwWidth) && (height == surf_ptr->surface_desc.dwHeight))) { + /* If not 'full size' and the surface is dirty, first flush it to GL before doing the copy. */ + gltex_flush_texture_memory_to_GL(surf_ptr); + } + + /* This is a hack and would need some clean-up :-) */ + if (gl_surf_ptr->initial_upload_done == FALSE) { + gl_surf_ptr->dirty_flag = SURFACE_MEMORY_DIRTY; + gltex_flush_texture_memory_to_GL(surf_ptr); + } + + if ((src_ptr->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0) + glReadBuffer(GL_FRONT); + else if ((src_ptr->surface_desc.ddsCaps.dwCaps & (DDSCAPS_BACKBUFFER)) == (DDSCAPS_BACKBUFFER)) + glReadBuffer(GL_BACK); + else { + ERR("Wrong surface type for locking !\n"); + LEAVE_GL(); + return DDERR_INVALIDPARAMS; + } + + for (y = src_ptr->surface_desc.dwHeight - rsrc->top; + y >= (src_ptr->surface_desc.dwHeight - (rsrc->top + height)); + y--) { + glCopyTexSubImage2D(GL_TEXTURE_2D, surf_ptr->mipmap_level, + dstx, dsty, + rsrc->left, y, + width, 1); + dsty++; + } + + glBindTexture(GL_TEXTURE_2D, cur_tex); + LEAVE_GL(); + + gl_surf_ptr->dirty_flag = SURFACE_GL; + + return DD_OK; + } + } + return DDERR_INVALIDPARAMS; +} + HRESULT WINAPI Main_IDirect3DTextureImpl_2_1T_PaletteChanged(LPDIRECT3DTEXTURE2 iface, DWORD dwStart, @@ -667,14 +799,26 @@ Main_IDirect3DTextureImpl_2_1T_Load(LPDIRECT3DTEXTURE2 iface, static void gltex_set_palette(IDirectDrawSurfaceImpl* This, IDirectDrawPaletteImpl* pal) { IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private; + + if (glThis->dirty_flag == SURFACE_GL) { + GLuint cur_tex; + + ENTER_GL(); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &cur_tex); + glBindTexture(GL_TEXTURE_2D, glThis->tex_name); + gltex_flush_texture_GL_to_memory(This); + glBindTexture(GL_TEXTURE_2D, cur_tex); + LEAVE_GL(); + } /* First call the previous set_palette function */ glThis->set_palette(This, pal); /* And set the dirty flag */ - glThis->dirty_flag = TRUE; - - /* TODO: check palette on mipmapped surfaces... */ + glThis->dirty_flag = SURFACE_MEMORY_DIRTY; + + /* TODO: check palette on mipmapped surfaces... + TODO: do we need to re-upload in case of usage of the paletted texture extension ? */ } static void @@ -728,7 +872,7 @@ gltex_unlock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect) /* Set the dirty flag according to the lock type */ if ((This->lastlocktype & DDLOCK_READONLY) == 0) - glThis->dirty_flag = TRUE; + glThis->dirty_flag = SURFACE_MEMORY_DIRTY; } HRESULT WINAPI @@ -817,7 +961,7 @@ GL_IDirect3DTextureImpl_2_1T_Load(LPDIRECT3DTEXTURE2 iface, if (gl_dst_ptr->tex_name == 0) ERR("Unbound GL texture !!!\n"); /* Set this texture as dirty */ - gl_dst_ptr->dirty_flag = TRUE; + gl_dst_ptr->dirty_flag = SURFACE_MEMORY_DIRTY; } } @@ -997,6 +1141,11 @@ HRESULT d3dtexture_create(IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *surf, BOOL surf->aux_setcolorkey_cb = gltex_setcolorkey_cb; surf->set_palette = gltex_set_palette; + /* We are the only one to use the aux_blt and aux_bltfast overides, so no need + to save those... */ + surf->aux_blt = gltex_blt; + surf->aux_bltfast = gltex_bltfast; + ENTER_GL(); if (surf->mipmap_level == 0) { glGenTextures(1, &(private->tex_name)); @@ -1010,7 +1159,7 @@ HRESULT d3dtexture_create(IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *surf, BOOL LEAVE_GL(); /* And set the dirty flag accordingly */ - private->dirty_flag = (at_creation == FALSE); + private->dirty_flag = (at_creation == FALSE ? SURFACE_MEMORY_DIRTY : SURFACE_MEMORY); private->initial_upload_done = FALSE; } diff --git a/dlls/ddraw/gl_api.h b/dlls/ddraw/gl_api.h index e19d6873dda..2257727db4e 100644 --- a/dlls/ddraw/gl_api.h +++ b/dlls/ddraw/gl_api.h @@ -39,6 +39,7 @@ GL_API_FUNCTION(glColor3f) GL_API_FUNCTION(glColor3ub) GL_API_FUNCTION(glColor4ub) GL_API_FUNCTION(glColorMaterial) +GL_API_FUNCTION(glCopyTexSubImage2D) GL_API_FUNCTION(glCullFace) GL_API_FUNCTION(glDeleteTextures) GL_API_FUNCTION(glDepthFunc) diff --git a/dlls/ddraw/gl_private.h b/dlls/ddraw/gl_private.h index a043424d58a..c45a89a0eb2 100644 --- a/dlls/ddraw/gl_private.h +++ b/dlls/ddraw/gl_private.h @@ -63,6 +63,7 @@ #define glColor3f pglColor3f #define glColor3ub pglColor3ub #define glColor4ub pglColor4ub +#define glCopyTexSubImage2D pglCopyTexSubImage2D #define glColorMaterial pglColorMaterial #define glCullFace pglCullFace #define glDeleteTextures pglDeleteTextures diff --git a/dlls/ddraw/mesa_private.h b/dlls/ddraw/mesa_private.h index 633d092a872..5bbab4098b2 100644 --- a/dlls/ddraw/mesa_private.h +++ b/dlls/ddraw/mesa_private.h @@ -39,6 +39,12 @@ extern void (*wine_tsx11_unlock_ptr)(void); extern const GUID IID_D3DDEVICE_OpenGL; +typedef enum { + SURFACE_GL, + SURFACE_MEMORY, + SURFACE_MEMORY_DIRTY +} SURFACE_STATE; + typedef struct IDirect3DGLImpl { struct IDirect3DImpl parent; @@ -60,7 +66,7 @@ typedef struct IDirect3DTextureGLImpl /* Texture upload management */ BOOLEAN initial_upload_done; - BOOLEAN dirty_flag; + SURFACE_STATE dirty_flag; /* Surface optimization */ void *surface_ptr; @@ -79,12 +85,6 @@ typedef enum { GL_TRANSFORM_VERTEXBUFFER } GL_TRANSFORM_STATE; -typedef enum { - SURFACE_GL, - SURFACE_MEMORY, - SURFACE_MEMORY_DIRTY -} SURFACE_STATE; - typedef struct IDirect3DDeviceGLImpl { struct IDirect3DDeviceImpl parent; -- 2.11.4.GIT