[PATCH] WineD3D: Beware of the frontbuffer coordinate system =
Stefan Doesinger
stefan at codeweavers.com
Sat Aug 2 17:59:50 CDT 2008
difference=0A=
=0A=
---=0A=
dlls/wined3d/device.c | 42 ++++++++++++++++++++++++++++++++----------=0A=
dlls/wined3d/surface.c | 36 +++++++++++++++++++++++++++---------=0A=
2 files changed, 59 insertions(+), 19 deletions(-)=0A=
=0A=
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c=0A=
index 12ec046..7892f35 100644=0A=
--- a/dlls/wined3d/device.c=0A=
+++ b/dlls/wined3d/device.c=0A=
@@ -6606,6 +6606,7 @@ void stretch_rect_fbo(IWineD3DDevice *iface, =
IWineD3DSurface *src_surface, WINED=0A=
GLbitfield mask =3D GL_COLOR_BUFFER_BIT; /* TODO: Support blitting =
depth/stencil surfaces */=0A=
IWineD3DSwapChain *src_swapchain, *dst_swapchain;=0A=
GLenum gl_filter;=0A=
+ POINT offset =3D {0, 0};=0A=
=0A=
TRACE("(%p) : src_surface %p, src_rect %p, dst_surface %p, dst_rect =
%p, filter %s (0x%08x), flip %u\n",=0A=
This, src_surface, src_rect, dst_surface, dst_rect, =
debug_d3dtexturefiltertype(filter), filter, flip);=0A=
@@ -6628,7 +6629,7 @@ void stretch_rect_fbo(IWineD3DDevice *iface, =
IWineD3DSurface *src_surface, WINED=0A=
/* Attach src surface to src fbo */=0A=
src_swapchain =3D get_swapchain(src_surface);=0A=
if (src_swapchain) {=0A=
- GLenum buffer;=0A=
+ GLenum buffer =3D surface_get_gl_buffer(src_surface, =
src_swapchain);=0A=
=0A=
TRACE("Source surface %p is onscreen\n", src_surface);=0A=
ActivateContext(This, src_surface, CTXUSAGE_RESOURCELOAD);=0A=
@@ -6636,14 +6637,24 @@ void stretch_rect_fbo(IWineD3DDevice *iface, =
IWineD3DSurface *src_surface, WINED=0A=
* attach_surface_fbo() implicitly takes care of this. */=0A=
IWineD3DSurface_LoadLocation(src_surface, SFLAG_INDRAWABLE, =
NULL);=0A=
=0A=
+ if(buffer =3D=3D GL_FRONT) {=0A=
+ RECT windowsize;=0A=
+ UINT h;=0A=
+ ClientToScreen(This->ddraw_window, &offset);=0A=
+ GetClientRect(This->ddraw_window, &windowsize);=0A=
+ h =3D windowsize.bottom - windowsize.top;=0A=
+ src_rect->x1 -=3D offset.x; dst_rect->x2 -=3Doffset.x;=0A=
+ src_rect->y1 =3D offset.y + h - src_rect->y1;=0A=
+ src_rect->y2 =3D offset.y + h - src_rect->y2;=0A=
+ } else {=0A=
+ src_rect->y1 =3D ((IWineD3DSurfaceImpl =
*)src_surface)->currentDesc.Height - src_rect->y1;=0A=
+ src_rect->y2 =3D ((IWineD3DSurfaceImpl =
*)src_surface)->currentDesc.Height - src_rect->y2;=0A=
+ }=0A=
+=0A=
ENTER_GL();=0A=
GL_EXTCALL(glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0));=0A=
- buffer =3D surface_get_gl_buffer(src_surface, src_swapchain);=0A=
glReadBuffer(buffer);=0A=
checkGLcall("glReadBuffer()");=0A=
-=0A=
- src_rect->y1 =3D ((IWineD3DSurfaceImpl =
*)src_surface)->currentDesc.Height - src_rect->y1;=0A=
- src_rect->y2 =3D ((IWineD3DSurfaceImpl =
*)src_surface)->currentDesc.Height - src_rect->y2;=0A=
} else {=0A=
TRACE("Source surface %p is offscreen\n", src_surface);=0A=
ENTER_GL();=0A=
@@ -6659,7 +6670,7 @@ void stretch_rect_fbo(IWineD3DDevice *iface, =
IWineD3DSurface *src_surface, WINED=0A=
/* Attach dst surface to dst fbo */=0A=
dst_swapchain =3D get_swapchain(dst_surface);=0A=
if (dst_swapchain) {=0A=
- GLenum buffer;=0A=
+ GLenum buffer =3D surface_get_gl_buffer(dst_surface, =
dst_swapchain);=0A=
=0A=
TRACE("Destination surface %p is onscreen\n", dst_surface);=0A=
ActivateContext(This, dst_surface, CTXUSAGE_RESOURCELOAD);=0A=
@@ -6667,14 +6678,25 @@ void stretch_rect_fbo(IWineD3DDevice *iface, =
IWineD3DSurface *src_surface, WINED=0A=
* attach_surface_fbo() implicitly takes care of this. */=0A=
IWineD3DSurface_LoadLocation(dst_surface, SFLAG_INDRAWABLE, =
NULL);=0A=
=0A=
+ if(buffer =3D=3D GL_FRONT) {=0A=
+ RECT windowsize;=0A=
+ UINT h;=0A=
+ ClientToScreen(This->ddraw_window, &offset);=0A=
+ GetClientRect(This->ddraw_window, &windowsize);=0A=
+ h =3D windowsize.bottom - windowsize.top;=0A=
+ dst_rect->x1 -=3D offset.x; dst_rect->x2 -=3Doffset.x;=0A=
+ dst_rect->y1 =3D offset.y + h - dst_rect->y1;=0A=
+ dst_rect->y2 =3D offset.y + h - dst_rect->y2;=0A=
+ } else {=0A=
+ /* Screen coords =3D window coords, surface height =3D =
window height */=0A=
+ dst_rect->y1 =3D ((IWineD3DSurfaceImpl =
*)dst_surface)->currentDesc.Height - dst_rect->y1;=0A=
+ dst_rect->y2 =3D ((IWineD3DSurfaceImpl =
*)dst_surface)->currentDesc.Height - dst_rect->y2;=0A=
+ }=0A=
+=0A=
ENTER_GL();=0A=
GL_EXTCALL(glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0));=0A=
- buffer =3D surface_get_gl_buffer(dst_surface, dst_swapchain);=0A=
glDrawBuffer(buffer);=0A=
checkGLcall("glDrawBuffer()");=0A=
-=0A=
- dst_rect->y1 =3D ((IWineD3DSurfaceImpl =
*)dst_surface)->currentDesc.Height - dst_rect->y1;=0A=
- dst_rect->y2 =3D ((IWineD3DSurfaceImpl =
*)dst_surface)->currentDesc.Height - dst_rect->y2;=0A=
} else {=0A=
TRACE("Destination surface %p is offscreen\n", dst_surface);=0A=
=0A=
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c=0A=
index 2227243..cb4d879 100644=0A=
--- a/dlls/wined3d/surface.c=0A=
+++ b/dlls/wined3d/surface.c=0A=
@@ -3268,6 +3268,7 @@ static HRESULT =
IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT *=0A=
WINEDDCOLORKEY oldBltCKey =3D Src->SrcBltCKey;=0A=
RECT SourceRectangle;=0A=
BOOL paletteOverride =3D FALSE;=0A=
+ GLenum buffer;=0A=
=0A=
TRACE("Blt from surface %p to rendertarget %p\n", Src, This);=0A=
=0A=
@@ -3340,22 +3341,39 @@ static HRESULT =
IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT *=0A=
=0A=
/* Activate the destination context, set it up for blitting */=0A=
ActivateContext(myDevice, (IWineD3DSurface *) This, =
CTXUSAGE_BLIT);=0A=
- ENTER_GL();=0A=
-=0A=
- glEnable(Src->glDescription.target);=0A=
- checkGLcall("glEnable(Src->glDescription.target)");=0A=
=0A=
if(!dstSwapchain) {=0A=
TRACE("Drawing to offscreen buffer\n");=0A=
- glDrawBuffer(myDevice->offscreenBuffer);=0A=
- checkGLcall("glDrawBuffer");=0A=
+ buffer =3D myDevice->offscreenBuffer;=0A=
} else {=0A=
- GLenum buffer =3D surface_get_gl_buffer((IWineD3DSurface =
*)This, (IWineD3DSwapChain *)dstSwapchain);=0A=
+ buffer =3D surface_get_gl_buffer((IWineD3DSurface *)This, =
(IWineD3DSwapChain *)dstSwapchain);=0A=
+=0A=
+ /* Front buffer coordinates are screen coordinates, while =
OpenGL coordinates are=0A=
+ * window relative. Also beware of the origin =
difference(top left vs bottom left).=0A=
+ * Also beware that the front buffer's surface size is =
screen width x screen height,=0A=
+ * whereas the real gl drawable size is the size of the =
window.=0A=
+ */=0A=
+ if(buffer =3D=3D GL_FRONT) {=0A=
+ RECT windowsize;=0A=
+ POINT offset =3D {0,0};=0A=
+ UINT h;=0A=
+ ClientToScreen(myDevice->ddraw_window, &offset);=0A=
+ GetClientRect(myDevice->ddraw_window, &windowsize);=0A=
+ h =3D windowsize.bottom - windowsize.top;=0A=
+ rect.x1 -=3D offset.x; rect.x2 -=3Doffset.x;=0A=
+ rect.y1 -=3D offset.y; rect.y2 -=3Doffset.y;=0A=
+ rect.y1 +=3D This->currentDesc.Height - h; rect.y2 +=3D =
This->currentDesc.Height - h;=0A=
+ }=0A=
TRACE("Drawing to %#x buffer\n", buffer);=0A=
- glDrawBuffer(buffer);=0A=
- checkGLcall("glDrawBuffer");=0A=
}=0A=
=0A=
+ ENTER_GL();=0A=
+ glDrawBuffer(buffer);=0A=
+ checkGLcall("glDrawBuffer");=0A=
+=0A=
+ glEnable(Src->glDescription.target);=0A=
+ checkGLcall("glEnable(Src->glDescription.target)");=0A=
+=0A=
/* Bind the texture */=0A=
glBindTexture(Src->glDescription.target, =
Src->glDescription.textureName);=0A=
checkGLcall("glBindTexture");=0A=
-- =0A=
1.5.4.5=0A=
=0A=
------=_NextPart_000_0023_01C8F509.2BB48220--
More information about the wine-patches
mailing list