Fixed bug 3345 - SDL_RenderClear inconsistency with ClipRect
authorSam Lantinga <slouken@libsdl.org>
Sat, 01 Oct 2016 11:46:32 -0700
changeset 10408d78b187845d6
parent 10407 16bfa598c1d6
child 10409 db023d8a1c8b
Fixed bug 3345 - SDL_RenderClear inconsistency with ClipRect

Simon Hug

The description of the SDL_RenderClear function in the SDL_render.h header says the following:

"This function clears the entire rendering target, ignoring the viewport."

The word "entire" implies that the clipping rectangle set with SDL_RenderSetClipRect also gets ignored. This is left somewhat ambiguous if only the viewport is mentioned. Minor thing, but let's see what the implementations actually do.

The software renderer ignores the clipping rectangle when clearing. It even has a comment on this: /* By definition the clear ignores the clip rect */

Most other render drivers (opengl, opengles, opengles2, direct3d, and psp [I assume. Can't test it.]) use the scissor test for the ClipRect and don't disable it when clearing. Clearing will only happen within the clipping rectangle for these drivers.

An exception is direct3d11 which uses a clear function that ignores the scissor test.
include/SDL_render.h
src/render/direct3d/SDL_render_d3d.c
src/render/opengl/SDL_render_gl.c
src/render/opengles/SDL_render_gles.c
src/render/opengles2/SDL_render_gles2.c
     1.1 --- a/include/SDL_render.h	Sat Oct 01 11:40:57 2016 -0700
     1.2 +++ b/include/SDL_render.h	Sat Oct 01 11:46:32 2016 -0700
     1.3 @@ -682,7 +682,8 @@
     1.4  /**
     1.5   *  \brief Clear the current rendering target with the drawing color
     1.6   *
     1.7 - *  This function clears the entire rendering target, ignoring the viewport.
     1.8 + *  This function clears the entire rendering target, ignoring the viewport and
     1.9 + *  the clip rectangle.
    1.10   *
    1.11   *  \return 0 on success, or -1 on error
    1.12   */
     2.1 --- a/src/render/direct3d/SDL_render_d3d.c	Sat Oct 01 11:40:57 2016 -0700
     2.2 +++ b/src/render/direct3d/SDL_render_d3d.c	Sat Oct 01 11:46:32 2016 -0700
     2.3 @@ -1311,6 +1311,10 @@
     2.4          BackBufferHeight = data->pparams.BackBufferHeight;
     2.5      }
     2.6  
     2.7 +    if (renderer->clipping_enabled) {
     2.8 +        IDirect3DDevice9_SetRenderState(data->device, D3DRS_SCISSORTESTENABLE, FALSE);
     2.9 +    }
    2.10 +
    2.11      /* Don't reset the viewport if we don't have to! */
    2.12      if (!renderer->viewport.x && !renderer->viewport.y &&
    2.13          renderer->viewport.w == BackBufferWidth &&
    2.14 @@ -1340,6 +1344,10 @@
    2.15          IDirect3DDevice9_SetViewport(data->device, &viewport);
    2.16      }
    2.17  
    2.18 +    if (renderer->clipping_enabled) {
    2.19 +        IDirect3DDevice9_SetRenderState(data->device, D3DRS_SCISSORTESTENABLE, TRUE);
    2.20 +    }
    2.21 +
    2.22      if (FAILED(result)) {
    2.23          return D3D_SetError("Clear()", result);
    2.24      }
     3.1 --- a/src/render/opengl/SDL_render_gl.c	Sat Oct 01 11:40:57 2016 -0700
     3.2 +++ b/src/render/opengl/SDL_render_gl.c	Sat Oct 01 11:46:32 2016 -0700
     3.3 @@ -1146,8 +1146,16 @@
     3.4                         (GLfloat) renderer->b * inv255f,
     3.5                         (GLfloat) renderer->a * inv255f);
     3.6  
     3.7 +    if (renderer->clipping_enabled) {
     3.8 +        data->glDisable(GL_SCISSOR_TEST);
     3.9 +    }
    3.10 +
    3.11      data->glClear(GL_COLOR_BUFFER_BIT);
    3.12  
    3.13 +    if (renderer->clipping_enabled) {
    3.14 +        data->glEnable(GL_SCISSOR_TEST);
    3.15 +    }
    3.16 +
    3.17      return 0;
    3.18  }
    3.19  
     4.1 --- a/src/render/opengles/SDL_render_gles.c	Sat Oct 01 11:40:57 2016 -0700
     4.2 +++ b/src/render/opengles/SDL_render_gles.c	Sat Oct 01 11:46:32 2016 -0700
     4.3 @@ -815,9 +815,17 @@
     4.4                   (GLfloat) renderer->g * inv255f,
     4.5                   (GLfloat) renderer->b * inv255f,
     4.6                   (GLfloat) renderer->a * inv255f);
     4.7 +    
     4.8 +    if (renderer->clipping_enabled) {
     4.9 +        data->glDisable(GL_SCISSOR_TEST);
    4.10 +    }
    4.11  
    4.12      data->glClear(GL_COLOR_BUFFER_BIT);
    4.13  
    4.14 +    if (renderer->clipping_enabled) {
    4.15 +        data->glEnable(GL_SCISSOR_TEST);
    4.16 +    }
    4.17 +
    4.18      return 0;
    4.19  }
    4.20  
     5.1 --- a/src/render/opengles2/SDL_render_gles2.c	Sat Oct 01 11:40:57 2016 -0700
     5.2 +++ b/src/render/opengles2/SDL_render_gles2.c	Sat Oct 01 11:46:32 2016 -0700
     5.3 @@ -1327,8 +1327,16 @@
     5.4          data->clear_a = renderer->a;
     5.5      }
     5.6  
     5.7 +    if (renderer->clipping_enabled) {
     5.8 +        data->glDisable(GL_SCISSOR_TEST);
     5.9 +    }
    5.10 +
    5.11      data->glClear(GL_COLOR_BUFFER_BIT);
    5.12  
    5.13 +    if (renderer->clipping_enabled) {
    5.14 +        data->glEnable(GL_SCISSOR_TEST);
    5.15 +    }
    5.16 +
    5.17      return 0;
    5.18  }
    5.19