Added function SDL_RenderSetClipRect()
authorSam Lantinga <slouken@libsdl.org>
Mon, 07 Feb 2011 20:06:26 -0800
changeset 5224 2178ffe17222
parent 5223 ab0d7cecc0f6
child 5225 5d01d426f2ea
Added function SDL_RenderSetClipRect()
include/SDL_render.h
src/render/SDL_render.c
src/render/SDL_sysrender.h
src/render/direct3d/SDL_render_d3d.c
src/render/opengl/SDL_glfuncs.h
src/render/opengl/SDL_render_gl.c
src/render/opengles/SDL_render_gles.c
src/render/opengles2/SDL_render_gles2.c
src/render/software/SDL_render_sw.c
--- a/include/SDL_render.h	Mon Feb 07 20:05:52 2011 -0800
+++ b/include/SDL_render.h	Mon Feb 07 20:06:26 2011 -0800
@@ -364,6 +364,18 @@
 extern DECLSPEC void SDLCALL SDL_UnlockTexture(SDL_Texture * texture);
 
 /**
+ *  \brief Set the clipping rectangle for rendering on the current target
+ *
+ *  \param rect The rectangle to clip rendering to, or NULL to disable clipping.
+ *
+ *  The contents of the window are not defined after calling
+ *  SDL_RenderPresent(), so you should clear the clip rectangle and draw
+ *  over the entire window each frame.
+ */
+extern DECLSPEC void SDLCALL SDL_RenderSetClipRect(SDL_Renderer * renderer,
+                                                   const SDL_Rect * rect);
+
+/**
  *  \brief Set the color used for drawing operations (Fill and Line).
  *  
  *  \param r The red value used to draw on the rendering target.
--- a/src/render/SDL_render.c	Mon Feb 07 20:05:52 2011 -0800
+++ b/src/render/SDL_render.c	Mon Feb 07 20:06:26 2011 -0800
@@ -725,6 +725,14 @@
     }
 }
 
+void
+SDL_RenderSetClipRect(SDL_Renderer * renderer, const SDL_Rect * rect)
+{
+    CHECK_RENDERER_MAGIC(renderer, );
+
+    renderer->SetClipRect(renderer, rect);
+}
+
 int
 SDL_SetRenderDrawColor(SDL_Renderer * renderer,
                        Uint8 r, Uint8 g, Uint8 b, Uint8 a)
--- a/src/render/SDL_sysrender.h	Mon Feb 07 20:05:52 2011 -0800
+++ b/src/render/SDL_sysrender.h	Mon Feb 07 20:06:26 2011 -0800
@@ -78,6 +78,7 @@
     int (*LockTexture) (SDL_Renderer * renderer, SDL_Texture * texture,
                         const SDL_Rect * rect, void **pixels, int *pitch);
     void (*UnlockTexture) (SDL_Renderer * renderer, SDL_Texture * texture);
+    void (*SetClipRect) (SDL_Renderer * renderer, const SDL_Rect *rect);
     int (*RenderClear) (SDL_Renderer * renderer);
     int (*RenderDrawPoints) (SDL_Renderer * renderer, const SDL_Point * points,
                              int count);
--- a/src/render/direct3d/SDL_render_d3d.c	Mon Feb 07 20:05:52 2011 -0800
+++ b/src/render/direct3d/SDL_render_d3d.c	Mon Feb 07 20:06:26 2011 -0800
@@ -96,6 +96,7 @@
 static int D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
                            const SDL_Rect * rect, void **pixels, int *pitch);
 static void D3D_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
+static void D3D_SetClipRect(SDL_Renderer * renderer, const SDL_Rect * rect);
 static int D3D_RenderDrawPoints(SDL_Renderer * renderer,
                                 const SDL_Point * points, int count);
 static int D3D_RenderDrawLines(SDL_Renderer * renderer,
@@ -308,6 +309,7 @@
     renderer->UpdateTexture = D3D_UpdateTexture;
     renderer->LockTexture = D3D_LockTexture;
     renderer->UnlockTexture = D3D_UnlockTexture;
+    renderer->SetClipRect = D3D_SetClipRect;
     renderer->RenderDrawPoints = D3D_RenderDrawPoints;
     renderer->RenderDrawLines = D3D_RenderDrawLines;
     renderer->RenderFillRects = D3D_RenderFillRects;
@@ -602,6 +604,27 @@
 }
 
 static void
+D3D_SetClipRect(SDL_Renderer * renderer, const SDL_Rect * rect)
+{
+    D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
+
+    if (rect) {
+        RECT d3drect;
+
+        d3drect.left = rect->x;
+        d3drect.right = rect->x + rect->w;
+        d3drect.top = rect->y;
+        d3drect.bottom = rect->y + rect->h;
+        IDirect3DDevice9_SetScissorRect(data->device, &d3drect);
+        IDirect3DDevice9_SetRenderState(data->device, D3DRS_SCISSORTESTENABLE,
+                                        TRUE);
+    } else {
+        IDirect3DDevice9_SetRenderState(data->device, D3DRS_SCISSORTESTENABLE,
+                                        FALSE);
+    }
+}
+
+static void
 D3D_SetBlendMode(D3D_RenderData * data, int blendMode)
 {
     switch (blendMode) {
--- a/src/render/opengl/SDL_glfuncs.h	Mon Feb 07 20:05:52 2011 -0800
+++ b/src/render/opengl/SDL_glfuncs.h	Mon Feb 07 20:06:26 2011 -0800
@@ -337,8 +337,7 @@
                 (GLfloat angle, GLfloat x, GLfloat y, GLfloat z))
 SDL_PROC_UNUSED(void, glScaled, (GLdouble x, GLdouble y, GLdouble z))
 SDL_PROC_UNUSED(void, glScalef, (GLfloat x, GLfloat y, GLfloat z))
-SDL_PROC_UNUSED(void, glScissor,
-                (GLint x, GLint y, GLsizei width, GLsizei height))
+SDL_PROC(void, glScissor, (GLint x, GLint y, GLsizei width, GLsizei height))
 SDL_PROC_UNUSED(void, glSelectBuffer, (GLsizei size, GLuint * buffer))
 SDL_PROC_UNUSED(void, glShadeModel, (GLenum mode))
 SDL_PROC_UNUSED(void, glStencilFunc, (GLenum func, GLint ref, GLuint mask))
--- a/src/render/opengl/SDL_render_gl.c	Mon Feb 07 20:05:52 2011 -0800
+++ b/src/render/opengl/SDL_render_gl.c	Mon Feb 07 20:06:26 2011 -0800
@@ -52,6 +52,7 @@
 static int GL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
                           const SDL_Rect * rect, void **pixels, int *pitch);
 static void GL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
+static void GL_SetClipRect(SDL_Renderer * renderer, const SDL_Rect * rect);
 static int GL_RenderClear(SDL_Renderer * renderer);
 static int GL_RenderDrawPoints(SDL_Renderer * renderer,
                                const SDL_Point * points, int count);
@@ -199,6 +200,7 @@
     renderer->UpdateTexture = GL_UpdateTexture;
     renderer->LockTexture = GL_LockTexture;
     renderer->UnlockTexture = GL_UnlockTexture;
+    renderer->SetClipRect = GL_SetClipRect;
     renderer->RenderClear = GL_RenderClear;
     renderer->RenderDrawPoints = GL_RenderDrawPoints;
     renderer->RenderDrawLines = GL_RenderDrawLines;
@@ -511,6 +513,24 @@
 }
 
 static void
+GL_SetClipRect(SDL_Renderer * renderer, const SDL_Rect * rect)
+{
+    GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
+
+    GL_ActivateRenderer(renderer);
+
+    if (rect) {
+        int w, h;
+
+        SDL_GetWindowSize(renderer->window, &w, &h);
+        data->glScissor(rect->x, (h-(rect->y+rect->h)), rect->w, rect->h);
+        data->glEnable(GL_SCISSOR_TEST);
+    } else {
+        data->glDisable(GL_SCISSOR_TEST);
+    }
+}
+
+static void
 GL_SetBlendMode(GL_RenderData * data, int blendMode)
 {
     if (blendMode != data->blendMode) {
--- a/src/render/opengles/SDL_render_gles.c	Mon Feb 07 20:05:52 2011 -0800
+++ b/src/render/opengles/SDL_render_gles.c	Mon Feb 07 20:06:26 2011 -0800
@@ -56,6 +56,7 @@
                             const SDL_Rect * rect, void **pixels, int *pitch);
 static void GLES_UnlockTexture(SDL_Renderer * renderer,
                                SDL_Texture * texture);
+static void GLES_SetClipRect(SDL_Renderer * renderer, const SDL_Rect * rect);
 static int GLES_RenderDrawPoints(SDL_Renderer * renderer,
                                  const SDL_Point * points, int count);
 static int GLES_RenderDrawLines(SDL_Renderer * renderer,
@@ -172,6 +173,7 @@
     renderer->UpdateTexture = GLES_UpdateTexture;
     renderer->LockTexture = GLES_LockTexture;
     renderer->UnlockTexture = GLES_UnlockTexture;
+    renderer->SetClipRect = GLES_SetClipRect;
     renderer->RenderDrawPoints = GLES_RenderDrawPoints;
     renderer->RenderDrawLines = GLES_RenderDrawLines;
     renderer->RenderFillRects = GLES_RenderFillRects;
@@ -444,6 +446,22 @@
 }
 
 static void
+GLES_SetClipRect(SDL_Renderer * renderer, const SDL_Rect * rect)
+{
+    GL_ActivateRenderer(renderer);
+
+    if (rect) {
+        int w, h;
+
+        SDL_GetWindowSize(renderer->window, &w, &h);
+        glScissor(rect->x, (h-(rect->y+rect->h)), rect->w, rect->h);
+        glEnable(GL_SCISSOR_TEST);
+    } else {
+        glDisable(GL_SCISSOR_TEST);
+    }
+}
+
+static void
 GLES_SetBlendMode(GLES_RenderData * data, int blendMode)
 {
     if (blendMode != data->blendMode) {
--- a/src/render/opengles2/SDL_render_gles2.c	Mon Feb 07 20:05:52 2011 -0800
+++ b/src/render/opengles2/SDL_render_gles2.c	Mon Feb 07 20:06:26 2011 -0800
@@ -133,10 +133,10 @@
  * Renderer state APIs                                                                           *
  *************************************************************************************************/
 
+static int GLES2_ActivateRenderer(SDL_Renderer *renderer);
 static void GLES2_WindowEvent(SDL_Renderer * renderer,
                               const SDL_WindowEvent *event);
-static int GLES2_ActivateRenderer(SDL_Renderer *renderer);
-static int GLES2_DisplayModeChanged(SDL_Renderer *renderer);
+static void GLES2_SetClipRect(SDL_Renderer * renderer, const SDL_Rect * rect);
 static void GLES2_DestroyRenderer(SDL_Renderer *renderer);
 
 static SDL_GLContext SDL_CurrentContext = NULL;
@@ -179,6 +179,22 @@
 }
 
 static void
+GLES2_SetClipRect(SDL_Renderer * renderer, const SDL_Rect * rect)
+{
+    GLES2_ActivateRenderer(renderer);
+
+    if (rect) {
+        int w, h;
+
+        SDL_GetWindowSize(renderer->window, &w, &h);
+        glScissor(rect->x, (h-(rect->y+rect->h)), rect->w, rect->h);
+        glEnable(GL_SCISSOR_TEST);
+    } else {
+        glDisable(GL_SCISSOR_TEST);
+    }
+}
+
+static void
 GLES2_DestroyRenderer(SDL_Renderer *renderer)
 {
     GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
@@ -761,6 +777,8 @@
  * Rendering functions                                                                           *
  *************************************************************************************************/
 
+static const float inv255f = 1.0f / 255.0f;
+
 static int GLES2_RenderClear(SDL_Renderer *renderer);
 static int GLES2_RenderDrawPoints(SDL_Renderer *renderer, const SDL_Point *points, int count);
 static int GLES2_RenderDrawLines(SDL_Renderer *renderer, const SDL_Point *points, int count);
@@ -772,10 +790,10 @@
 static int
 GLES2_RenderClear(SDL_Renderer *renderer)
 {
-    float r = (float)renderer->r / 255.0f;
-    float g = (float)renderer->g / 255.0f;
-    float b = (float)renderer->b / 255.0f;
-    float a = (float)renderer->a / 255.0f;
+    float r = (float)renderer->r * inv255f;
+    float g = (float)renderer->g * inv255f;
+    float b = (float)renderer->b * inv255f;
+    float a = (float)renderer->a * inv255f;
 
     GLES2_ActivateRenderer(renderer);
 
@@ -832,10 +850,10 @@
     locColor = rdata->current_program->uniform_locations[GLES2_UNIFORM_COLOR];
     glGetError();
     glUniform4f(locColor,
-                renderer->r / 255.0f,
-                renderer->g / 255.0f,
-                renderer->b / 255.0f,
-                alpha / 255.0f);
+                renderer->r * inv255f,
+                renderer->g * inv255f,
+                renderer->b * inv255f,
+                alpha * inv255f);
 
     /* Configure the correct blend mode */
     GLES2_SetBlendMode(blendMode);
@@ -886,10 +904,10 @@
     locColor = rdata->current_program->uniform_locations[GLES2_UNIFORM_COLOR];
     glGetError();
     glUniform4f(locColor,
-                renderer->r / 255.0f,
-                renderer->g / 255.0f,
-                renderer->b / 255.0f,
-                alpha / 255.0f);
+                renderer->r * inv255f,
+                renderer->g * inv255f,
+                renderer->b * inv255f,
+                alpha * inv255f);
 
     /* Configure the correct blend mode */
     GLES2_SetBlendMode(blendMode);
@@ -940,10 +958,10 @@
     locColor = rdata->current_program->uniform_locations[GLES2_UNIFORM_COLOR];
     glGetError();
     glUniform4f(locColor,
-                renderer->r / 255.0f,
-                renderer->g / 255.0f,
-                renderer->b / 255.0f,
-                alpha / 255.0f);
+                renderer->r * inv255f,
+                renderer->g * inv255f,
+                renderer->b * inv255f,
+                alpha * inv255f);
 
     /* Configure the correct blend mode */
     GLES2_SetBlendMode(blendMode);
@@ -1014,10 +1032,10 @@
     /* Configure color modulation */
     locModulation = rdata->current_program->uniform_locations[GLES2_UNIFORM_MODULATION];
     glUniform4f(locModulation,
-                texture->r / 255.0f,
-                texture->g / 255.0f,
-                texture->b / 255.0f,
-                alpha / 255.0f);
+                texture->r * inv255f,
+                texture->g * inv255f,
+                texture->b * inv255f,
+                alpha * inv255f);
 
     /* Emit the textured quad */
     glEnableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD);
@@ -1066,6 +1084,9 @@
 
 #define GL_NVIDIA_PLATFORM_BINARY_NV 0x890B
 
+/* Used to re-create the window with OpenGL capability */
+extern int SDL_RecreateWindow(SDL_Window * window, Uint32 flags);
+
 static SDL_Renderer *
 GLES2_CreateRenderer(SDL_Window *window, Uint32 flags)
 {
@@ -1168,6 +1189,7 @@
     renderer->UpdateTexture       = &GLES2_UpdateTexture;
     renderer->LockTexture         = &GLES2_LockTexture;
     renderer->UnlockTexture       = &GLES2_UnlockTexture;
+    renderer->SetClipRect         = &GLES2_SetClipRect;
     renderer->RenderClear         = &GLES2_RenderClear;
     renderer->RenderDrawPoints    = &GLES2_RenderDrawPoints;
     renderer->RenderDrawLines     = &GLES2_RenderDrawLines;
--- a/src/render/software/SDL_render_sw.c	Mon Feb 07 20:05:52 2011 -0800
+++ b/src/render/software/SDL_render_sw.c	Mon Feb 07 20:06:26 2011 -0800
@@ -50,6 +50,7 @@
 static int SW_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
                           const SDL_Rect * rect, void **pixels, int *pitch);
 static void SW_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
+static void SW_SetClipRect(SDL_Renderer * renderer, const SDL_Rect * rect);
 static int SW_RenderDrawPoints(SDL_Renderer * renderer,
                                const SDL_Point * points, int count);
 static int SW_RenderDrawLines(SDL_Renderer * renderer,
@@ -125,6 +126,7 @@
     renderer->UpdateTexture = SW_UpdateTexture;
     renderer->LockTexture = SW_LockTexture;
     renderer->UnlockTexture = SW_UnlockTexture;
+    renderer->SetClipRect = SW_SetClipRect;
     renderer->DestroyTexture = SW_DestroyTexture;
     renderer->RenderDrawPoints = SW_RenderDrawPoints;
     renderer->RenderDrawLines = SW_RenderDrawLines;
@@ -266,6 +268,17 @@
 {
 }
 
+static void
+SW_SetClipRect(SDL_Renderer * renderer, const SDL_Rect * rect)
+{
+    SDL_Surface *surface = SW_ActivateRenderer(renderer);
+
+    if (!surface) {
+        return;
+    }
+    SDL_SetClipRect(surface, rect);
+}
+
 static int
 SW_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points,
                     int count)