Browse Source

Fixed clip rectangle calculation when there is a viewport offset

Sam Lantinga 10 years ago
parent
commit
da1909755b

+ 4 - 4
src/render/direct3d/SDL_render_d3d.c

@@ -1269,10 +1269,10 @@ D3D_UpdateClipRect(SDL_Renderer * renderer)
         HRESULT result;
         HRESULT result;
 
 
         IDirect3DDevice9_SetRenderState(data->device, D3DRS_SCISSORTESTENABLE, TRUE);
         IDirect3DDevice9_SetRenderState(data->device, D3DRS_SCISSORTESTENABLE, TRUE);
-        r.left = rect->x;
-        r.top = rect->y;
-        r.right = rect->x + rect->w;
-        r.bottom = rect->y + rect->h;
+        r.left = renderer->viewport.x + rect->x;
+        r.top = renderer->viewport.y + rect->y;
+        r.right = renderer->viewport.x + rect->x + rect->w;
+        r.bottom = renderer->viewport.y + rect->y + rect->h;
 
 
         result = IDirect3DDevice9_SetScissorRect(data->device, &r);
         result = IDirect3DDevice9_SetScissorRect(data->device, &r);
         if (result != D3D_OK) {
         if (result != D3D_OK) {

+ 9 - 3
src/render/direct3d11/SDL_render_d3d11.c

@@ -1356,7 +1356,7 @@ D3D11_GetRotationForCurrentRenderTarget(SDL_Renderer * renderer)
 }
 }
 
 
 static int
 static int
-D3D11_GetViewportAlignedD3DRect(SDL_Renderer * renderer, const SDL_Rect * sdlRect, D3D11_RECT * outRect)
+D3D11_GetViewportAlignedD3DRect(SDL_Renderer * renderer, const SDL_Rect * sdlRect, D3D11_RECT * outRect, BOOL includeViewportOffset)
 {
 {
     D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
     D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
     const int rotation = D3D11_GetRotationForCurrentRenderTarget(renderer);
     const int rotation = D3D11_GetRotationForCurrentRenderTarget(renderer);
@@ -1366,6 +1366,12 @@ D3D11_GetViewportAlignedD3DRect(SDL_Renderer * renderer, const SDL_Rect * sdlRec
             outRect->right = sdlRect->x + sdlRect->w;
             outRect->right = sdlRect->x + sdlRect->w;
             outRect->top = sdlRect->y;
             outRect->top = sdlRect->y;
             outRect->bottom = sdlRect->y + sdlRect->h;
             outRect->bottom = sdlRect->y + sdlRect->h;
+            if (includeViewportOffset) {
+                outRect->left += renderer->viewport.x;
+                outRect->right += renderer->viewport.x;
+                outRect->top += renderer->viewport.y;
+                outRect->bottom += renderer->viewport.y;
+            }
             break;
             break;
         case DXGI_MODE_ROTATION_ROTATE270:
         case DXGI_MODE_ROTATION_ROTATE270:
             outRect->left = sdlRect->y;
             outRect->left = sdlRect->y;
@@ -2280,7 +2286,7 @@ D3D11_UpdateClipRect(SDL_Renderer * renderer)
         ID3D11DeviceContext_RSSetScissorRects(data->d3dContext, 0, NULL);
         ID3D11DeviceContext_RSSetScissorRects(data->d3dContext, 0, NULL);
     } else {
     } else {
         D3D11_RECT scissorRect;
         D3D11_RECT scissorRect;
-        if (D3D11_GetViewportAlignedD3DRect(renderer, &renderer->clip_rect, &scissorRect) != 0) {
+        if (D3D11_GetViewportAlignedD3DRect(renderer, &renderer->clip_rect, &scissorRect, TRUE) != 0) {
             /* D3D11_GetViewportAlignedD3DRect will have set the SDL error */
             /* D3D11_GetViewportAlignedD3DRect will have set the SDL error */
             return -1;
             return -1;
         }
         }
@@ -2869,7 +2875,7 @@ D3D11_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
     }
     }
 
 
     /* Copy the desired portion of the back buffer to the staging texture: */
     /* Copy the desired portion of the back buffer to the staging texture: */
-    if (D3D11_GetViewportAlignedD3DRect(renderer, rect, &srcRect) != 0) {
+    if (D3D11_GetViewportAlignedD3DRect(renderer, rect, &srcRect, FALSE) != 0) {
         /* D3D11_GetViewportAlignedD3DRect will have set the SDL error */
         /* D3D11_GetViewportAlignedD3DRect will have set the SDL error */
         goto done;
         goto done;
     }
     }

+ 8 - 1
src/render/opengl/SDL_render_gl.c

@@ -1046,7 +1046,14 @@ GL_UpdateClipRect(SDL_Renderer * renderer)
     if (renderer->clipping_enabled) {
     if (renderer->clipping_enabled) {
         const SDL_Rect *rect = &renderer->clip_rect;
         const SDL_Rect *rect = &renderer->clip_rect;
         data->glEnable(GL_SCISSOR_TEST);
         data->glEnable(GL_SCISSOR_TEST);
-        data->glScissor(rect->x, renderer->viewport.h - rect->y - rect->h, rect->w, rect->h);
+        if (renderer->target) {
+            data->glScissor(renderer->viewport.x + rect->x, renderer->viewport.y + rect->y, rect->w, rect->h);
+        } else {
+            int w, h;
+
+            SDL_GetRendererOutputSize(renderer, &w, &h);
+            data->glScissor(renderer->viewport.x + rect->x, (h - renderer->viewport.y - renderer->viewport.h) + rect->y, rect->w, rect->h);
+        }
     } else {
     } else {
         data->glDisable(GL_SCISSOR_TEST);
         data->glDisable(GL_SCISSOR_TEST);
     }
     }

+ 18 - 3
src/render/opengles/SDL_render_gles.c

@@ -680,8 +680,16 @@ GLES_UpdateViewport(SDL_Renderer * renderer)
         return 0;
         return 0;
     }
     }
 
 
-    data->glViewport(renderer->viewport.x, renderer->viewport.y,
-               renderer->viewport.w, renderer->viewport.h);
+    if (renderer->target) {
+        data->glViewport(renderer->viewport.x, renderer->viewport.y,
+                         renderer->viewport.w, renderer->viewport.h);
+    } else {
+        int w, h;
+
+        SDL_GetRendererOutputSize(renderer, &w, &h);
+        data->glViewport(renderer->viewport.x, (h - renderer->viewport.y - renderer->viewport.h),
+                         renderer->viewport.w, renderer->viewport.h);
+    }
 
 
     if (renderer->viewport.w && renderer->viewport.h) {
     if (renderer->viewport.w && renderer->viewport.h) {
         data->glMatrixMode(GL_PROJECTION);
         data->glMatrixMode(GL_PROJECTION);
@@ -707,7 +715,14 @@ GLES_UpdateClipRect(SDL_Renderer * renderer)
     if (renderer->clipping_enabled) {
     if (renderer->clipping_enabled) {
         const SDL_Rect *rect = &renderer->clip_rect;
         const SDL_Rect *rect = &renderer->clip_rect;
         data->glEnable(GL_SCISSOR_TEST);
         data->glEnable(GL_SCISSOR_TEST);
-        data->glScissor(rect->x, renderer->viewport.h - rect->y - rect->h, rect->w, rect->h);
+        if (renderer->target) {
+            data->glScissor(renderer->viewport.x + rect->x, renderer->viewport.y + rect->y, rect->w, rect->h);
+        } else {
+            int w, h;
+
+            SDL_GetRendererOutputSize(renderer, &w, &h);
+            data->glScissor(renderer->viewport.x + rect->x, (h - renderer->viewport.y - renderer->viewport.h) + rect->y, rect->w, rect->h);
+        }
     } else {
     } else {
         data->glDisable(GL_SCISSOR_TEST);
         data->glDisable(GL_SCISSOR_TEST);
     }
     }

+ 18 - 3
src/render/opengles2/SDL_render_gles2.c

@@ -382,8 +382,16 @@ GLES2_UpdateViewport(SDL_Renderer * renderer)
         return 0;
         return 0;
     }
     }
 
 
-    data->glViewport(renderer->viewport.x, renderer->viewport.y,
-               renderer->viewport.w, renderer->viewport.h);
+    if (renderer->target) {
+        data->glViewport(renderer->viewport.x, renderer->viewport.y,
+                         renderer->viewport.w, renderer->viewport.h);
+    } else {
+        int w, h;
+
+        SDL_GetRendererOutputSize(renderer, &w, &h);
+        data->glViewport(renderer->viewport.x, (h - renderer->viewport.y - renderer->viewport.h),
+                         renderer->viewport.w, renderer->viewport.h);
+    }
 
 
     if (data->current_program) {
     if (data->current_program) {
         GLES2_SetOrthographicProjection(renderer);
         GLES2_SetOrthographicProjection(renderer);
@@ -404,7 +412,14 @@ GLES2_UpdateClipRect(SDL_Renderer * renderer)
     if (renderer->clipping_enabled) {
     if (renderer->clipping_enabled) {
         const SDL_Rect *rect = &renderer->clip_rect;
         const SDL_Rect *rect = &renderer->clip_rect;
         data->glEnable(GL_SCISSOR_TEST);
         data->glEnable(GL_SCISSOR_TEST);
-        data->glScissor(rect->x, renderer->viewport.h - rect->y - rect->h, rect->w, rect->h);
+        if (renderer->target) {
+            data->glScissor(renderer->viewport.x + rect->x, renderer->viewport.y + rect->y, rect->w, rect->h);
+        } else {
+            int w, h;
+
+            SDL_GetRendererOutputSize(renderer, &w, &h);
+            data->glScissor(renderer->viewport.x + rect->x, (h - renderer->viewport.y - renderer->viewport.h) + rect->y, rect->w, rect->h);
+        }
     } else {
     } else {
         data->glDisable(GL_SCISSOR_TEST);
         data->glDisable(GL_SCISSOR_TEST);
     }
     }