[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