wined3d: Beware of the frontbuffer coordinate system difference.

This commit is contained in:
Stefan Dösinger 2008-08-03 11:33:07 -05:00 committed by Alexandre Julliard
parent 016efe7d94
commit 474e7ed98c
2 changed files with 59 additions and 19 deletions

View File

@ -6606,6 +6606,7 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED
GLbitfield mask = GL_COLOR_BUFFER_BIT; /* TODO: Support blitting depth/stencil surfaces */ GLbitfield mask = GL_COLOR_BUFFER_BIT; /* TODO: Support blitting depth/stencil surfaces */
IWineD3DSwapChain *src_swapchain, *dst_swapchain; IWineD3DSwapChain *src_swapchain, *dst_swapchain;
GLenum gl_filter; GLenum gl_filter;
POINT offset = {0, 0};
TRACE("(%p) : src_surface %p, src_rect %p, dst_surface %p, dst_rect %p, filter %s (0x%08x), flip %u\n", TRACE("(%p) : src_surface %p, src_rect %p, dst_surface %p, dst_rect %p, filter %s (0x%08x), flip %u\n",
This, src_surface, src_rect, dst_surface, dst_rect, debug_d3dtexturefiltertype(filter), filter, flip); This, src_surface, src_rect, dst_surface, dst_rect, debug_d3dtexturefiltertype(filter), filter, flip);
@ -6628,7 +6629,7 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED
/* Attach src surface to src fbo */ /* Attach src surface to src fbo */
src_swapchain = get_swapchain(src_surface); src_swapchain = get_swapchain(src_surface);
if (src_swapchain) { if (src_swapchain) {
GLenum buffer; GLenum buffer = surface_get_gl_buffer(src_surface, src_swapchain);
TRACE("Source surface %p is onscreen\n", src_surface); TRACE("Source surface %p is onscreen\n", src_surface);
ActivateContext(This, src_surface, CTXUSAGE_RESOURCELOAD); ActivateContext(This, src_surface, CTXUSAGE_RESOURCELOAD);
@ -6636,14 +6637,24 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED
* attach_surface_fbo() implicitly takes care of this. */ * attach_surface_fbo() implicitly takes care of this. */
IWineD3DSurface_LoadLocation(src_surface, SFLAG_INDRAWABLE, NULL); IWineD3DSurface_LoadLocation(src_surface, SFLAG_INDRAWABLE, NULL);
if(buffer == GL_FRONT) {
RECT windowsize;
UINT h;
ClientToScreen(This->ddraw_window, &offset);
GetClientRect(This->ddraw_window, &windowsize);
h = windowsize.bottom - windowsize.top;
src_rect->x1 -= offset.x; src_rect->x2 -=offset.x;
src_rect->y1 = offset.y + h - src_rect->y1;
src_rect->y2 = offset.y + h - src_rect->y2;
} else {
src_rect->y1 = ((IWineD3DSurfaceImpl *)src_surface)->currentDesc.Height - src_rect->y1;
src_rect->y2 = ((IWineD3DSurfaceImpl *)src_surface)->currentDesc.Height - src_rect->y2;
}
ENTER_GL(); ENTER_GL();
GL_EXTCALL(glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0)); GL_EXTCALL(glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0));
buffer = surface_get_gl_buffer(src_surface, src_swapchain);
glReadBuffer(buffer); glReadBuffer(buffer);
checkGLcall("glReadBuffer()"); checkGLcall("glReadBuffer()");
src_rect->y1 = ((IWineD3DSurfaceImpl *)src_surface)->currentDesc.Height - src_rect->y1;
src_rect->y2 = ((IWineD3DSurfaceImpl *)src_surface)->currentDesc.Height - src_rect->y2;
} else { } else {
TRACE("Source surface %p is offscreen\n", src_surface); TRACE("Source surface %p is offscreen\n", src_surface);
ENTER_GL(); ENTER_GL();
@ -6659,7 +6670,7 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED
/* Attach dst surface to dst fbo */ /* Attach dst surface to dst fbo */
dst_swapchain = get_swapchain(dst_surface); dst_swapchain = get_swapchain(dst_surface);
if (dst_swapchain) { if (dst_swapchain) {
GLenum buffer; GLenum buffer = surface_get_gl_buffer(dst_surface, dst_swapchain);
TRACE("Destination surface %p is onscreen\n", dst_surface); TRACE("Destination surface %p is onscreen\n", dst_surface);
ActivateContext(This, dst_surface, CTXUSAGE_RESOURCELOAD); ActivateContext(This, dst_surface, CTXUSAGE_RESOURCELOAD);
@ -6667,14 +6678,25 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED
* attach_surface_fbo() implicitly takes care of this. */ * attach_surface_fbo() implicitly takes care of this. */
IWineD3DSurface_LoadLocation(dst_surface, SFLAG_INDRAWABLE, NULL); IWineD3DSurface_LoadLocation(dst_surface, SFLAG_INDRAWABLE, NULL);
if(buffer == GL_FRONT) {
RECT windowsize;
UINT h;
ClientToScreen(This->ddraw_window, &offset);
GetClientRect(This->ddraw_window, &windowsize);
h = windowsize.bottom - windowsize.top;
dst_rect->x1 -= offset.x; dst_rect->x2 -=offset.x;
dst_rect->y1 = offset.y + h - dst_rect->y1;
dst_rect->y2 = offset.y + h - dst_rect->y2;
} else {
/* Screen coords = window coords, surface height = window height */
dst_rect->y1 = ((IWineD3DSurfaceImpl *)dst_surface)->currentDesc.Height - dst_rect->y1;
dst_rect->y2 = ((IWineD3DSurfaceImpl *)dst_surface)->currentDesc.Height - dst_rect->y2;
}
ENTER_GL(); ENTER_GL();
GL_EXTCALL(glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0)); GL_EXTCALL(glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0));
buffer = surface_get_gl_buffer(dst_surface, dst_swapchain);
glDrawBuffer(buffer); glDrawBuffer(buffer);
checkGLcall("glDrawBuffer()"); checkGLcall("glDrawBuffer()");
dst_rect->y1 = ((IWineD3DSurfaceImpl *)dst_surface)->currentDesc.Height - dst_rect->y1;
dst_rect->y2 = ((IWineD3DSurfaceImpl *)dst_surface)->currentDesc.Height - dst_rect->y2;
} else { } else {
TRACE("Destination surface %p is offscreen\n", dst_surface); TRACE("Destination surface %p is offscreen\n", dst_surface);

View File

@ -3268,6 +3268,7 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT *
WINEDDCOLORKEY oldBltCKey = Src->SrcBltCKey; WINEDDCOLORKEY oldBltCKey = Src->SrcBltCKey;
RECT SourceRectangle; RECT SourceRectangle;
BOOL paletteOverride = FALSE; BOOL paletteOverride = FALSE;
GLenum buffer;
TRACE("Blt from surface %p to rendertarget %p\n", Src, This); TRACE("Blt from surface %p to rendertarget %p\n", Src, This);
@ -3340,22 +3341,39 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT *
/* Activate the destination context, set it up for blitting */ /* Activate the destination context, set it up for blitting */
ActivateContext(myDevice, (IWineD3DSurface *) This, CTXUSAGE_BLIT); ActivateContext(myDevice, (IWineD3DSurface *) This, CTXUSAGE_BLIT);
ENTER_GL();
glEnable(Src->glDescription.target);
checkGLcall("glEnable(Src->glDescription.target)");
if(!dstSwapchain) { if(!dstSwapchain) {
TRACE("Drawing to offscreen buffer\n"); TRACE("Drawing to offscreen buffer\n");
glDrawBuffer(myDevice->offscreenBuffer); buffer = myDevice->offscreenBuffer;
checkGLcall("glDrawBuffer");
} else { } else {
GLenum buffer = surface_get_gl_buffer((IWineD3DSurface *)This, (IWineD3DSwapChain *)dstSwapchain); buffer = surface_get_gl_buffer((IWineD3DSurface *)This, (IWineD3DSwapChain *)dstSwapchain);
/* Front buffer coordinates are screen coordinates, while OpenGL coordinates are
* window relative. Also beware of the origin difference(top left vs bottom left).
* Also beware that the front buffer's surface size is screen width x screen height,
* whereas the real gl drawable size is the size of the window.
*/
if(buffer == GL_FRONT) {
RECT windowsize;
POINT offset = {0,0};
UINT h;
ClientToScreen(myDevice->ddraw_window, &offset);
GetClientRect(myDevice->ddraw_window, &windowsize);
h = windowsize.bottom - windowsize.top;
rect.x1 -= offset.x; rect.x2 -=offset.x;
rect.y1 -= offset.y; rect.y2 -=offset.y;
rect.y1 += This->currentDesc.Height - h; rect.y2 += This->currentDesc.Height - h;
}
TRACE("Drawing to %#x buffer\n", buffer); TRACE("Drawing to %#x buffer\n", buffer);
glDrawBuffer(buffer);
checkGLcall("glDrawBuffer");
} }
ENTER_GL();
glDrawBuffer(buffer);
checkGLcall("glDrawBuffer");
glEnable(Src->glDescription.target);
checkGLcall("glEnable(Src->glDescription.target)");
/* Bind the texture */ /* Bind the texture */
glBindTexture(Src->glDescription.target, Src->glDescription.textureName); glBindTexture(Src->glDescription.target, Src->glDescription.textureName);
checkGLcall("glBindTexture"); checkGLcall("glBindTexture");