src/render/SDL_render.c
changeset 8477 ad08f0d710f3
parent 8464 a2a909304cfe
parent 7563 c128ed448c30
child 8478 337b5dc0797b
     1.1 --- a/src/render/SDL_render.c	Sat Jun 08 14:34:09 2013 -0400
     1.2 +++ b/src/render/SDL_render.c	Mon Aug 12 22:29:55 2013 -0400
     1.3 @@ -44,14 +44,11 @@
     1.4      }
     1.5  
     1.6  
     1.7 +#if !SDL_RENDER_DISABLED
     1.8  static const SDL_RenderDriver *render_drivers[] = {
     1.9 -#if !SDL_RENDER_DISABLED
    1.10  #if SDL_VIDEO_RENDER_D3D
    1.11      &D3D_RenderDriver,
    1.12  #endif
    1.13 -//#if SDL_VIDEO_RENDER_D3D11
    1.14 -//    &D3D11_RenderDriver,
    1.15 -//#endif
    1.16  #if SDL_VIDEO_RENDER_OGL
    1.17      &GL_RenderDriver,
    1.18  #endif
    1.19 @@ -67,13 +64,10 @@
    1.20  #if SDL_VIDEO_RENDER_PSP
    1.21      &PSP_RenderDriver,
    1.22  #endif
    1.23 -    &SW_RenderDriver,
    1.24 -#if SDL_VIDEO_RENDER_D3D11
    1.25 -    // WinRT, TODO: once the Direct3D 11.1 renderer is ready, make it be used over the SW renderer via SDL_CreateRenderer(window, -1, 0)
    1.26 -    &D3D11_RenderDriver
    1.27 -#endif
    1.28 +    &SW_RenderDriver
    1.29 +};
    1.30  #endif /* !SDL_RENDER_DISABLED */
    1.31 -};
    1.32 +
    1.33  static char renderer_magic;
    1.34  static char texture_magic;
    1.35  
    1.36 @@ -82,18 +76,26 @@
    1.37  int
    1.38  SDL_GetNumRenderDrivers(void)
    1.39  {
    1.40 +#if !SDL_RENDER_DISABLED
    1.41      return SDL_arraysize(render_drivers);
    1.42 +#else
    1.43 +    return 0;
    1.44 +#endif
    1.45  }
    1.46  
    1.47  int
    1.48  SDL_GetRenderDriverInfo(int index, SDL_RendererInfo * info)
    1.49  {
    1.50 +#if !SDL_RENDER_DISABLED
    1.51      if (index < 0 || index >= SDL_GetNumRenderDrivers()) {
    1.52          return SDL_SetError("index must be in the range of 0 - %d",
    1.53                              SDL_GetNumRenderDrivers() - 1);
    1.54      }
    1.55      *info = render_drivers[index]->info;
    1.56      return 0;
    1.57 +#else
    1.58 +    return SDL_SetError("SDL not built with rendering support");
    1.59 +#endif
    1.60  }
    1.61  
    1.62  static int
    1.63 @@ -108,29 +110,11 @@
    1.64                  renderer->WindowEvent(renderer, &event->window);
    1.65              }
    1.66  
    1.67 -            if (event->window.event == SDL_WINDOWEVENT_RESIZED) {
    1.68 -                if (renderer->logical_w) {
    1.69 -                    /* We'll update the renderer in the SIZE_CHANGED event */
    1.70 -                } else {
    1.71 -                    /* Try to keep the previous viewport centered */
    1.72 -                    int w, h;
    1.73 -
    1.74 -                    SDL_GetWindowSize(window, &w, &h);
    1.75 -                    if (renderer->target) {
    1.76 -                        renderer->viewport_backup.x = (w - renderer->viewport_backup.w) / 2;
    1.77 -                        renderer->viewport_backup.y = (h - renderer->viewport_backup.h) / 2;
    1.78 -                    } else {
    1.79 -                        renderer->viewport.x = (w - renderer->viewport.w) / 2;
    1.80 -                        renderer->viewport.y = (h - renderer->viewport.h) / 2;
    1.81 -                        renderer->UpdateViewport(renderer);
    1.82 -                    }
    1.83 -                }
    1.84 -                renderer->resized = SDL_TRUE;
    1.85 -            } else if (event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
    1.86 +            if (event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
    1.87                  if (renderer->logical_w) {
    1.88                      UpdateLogicalSize(renderer);
    1.89 -                } else if (!renderer->resized) {
    1.90 -                    /* Window was programmatically resized, reset viewport */
    1.91 +                } else {
    1.92 +                    /* Window was resized, reset viewport */
    1.93                      int w, h;
    1.94  
    1.95                      SDL_GetWindowSize(window, &w, &h);
    1.96 @@ -147,7 +131,6 @@
    1.97                          renderer->UpdateViewport(renderer);
    1.98                      }
    1.99                  }
   1.100 -                renderer->resized = SDL_FALSE;
   1.101              } else if (event->window.event == SDL_WINDOWEVENT_HIDDEN) {
   1.102                  renderer->hidden = SDL_TRUE;
   1.103              } else if (event->window.event == SDL_WINDOWEVENT_SHOWN) {
   1.104 @@ -168,6 +151,16 @@
   1.105              event->motion.y -= renderer->viewport.y;
   1.106              event->motion.x = (int)(event->motion.x / renderer->scale.x);
   1.107              event->motion.y = (int)(event->motion.y / renderer->scale.y);
   1.108 +            if (event->motion.xrel > 0) {
   1.109 +                event->motion.xrel = SDL_max(1, (int)(event->motion.xrel / renderer->scale.x));
   1.110 +            } else if (event->motion.xrel < 0) {
   1.111 +                event->motion.xrel = SDL_min(-1, (int)(event->motion.xrel / renderer->scale.x));
   1.112 +            }
   1.113 +            if (event->motion.yrel > 0) {
   1.114 +                event->motion.yrel = SDL_max(1, (int)(event->motion.yrel / renderer->scale.y));
   1.115 +            } else if (event->motion.yrel < 0) {
   1.116 +                event->motion.yrel = SDL_min(-1, (int)(event->motion.yrel / renderer->scale.y));
   1.117 +            }
   1.118          }
   1.119      } else if (event->type == SDL_MOUSEBUTTONDOWN ||
   1.120                 event->type == SDL_MOUSEBUTTONUP) {
   1.121 @@ -204,6 +197,7 @@
   1.122  SDL_Renderer *
   1.123  SDL_CreateRenderer(SDL_Window * window, int index, Uint32 flags)
   1.124  {
   1.125 +#if !SDL_RENDER_DISABLED
   1.126      SDL_Renderer *renderer = NULL;
   1.127      int n = SDL_GetNumRenderDrivers();
   1.128      const char *hint;
   1.129 @@ -291,6 +285,10 @@
   1.130                      "Created renderer: %s", renderer->info.name);
   1.131      }
   1.132      return renderer;
   1.133 +#else
   1.134 +    SDL_SetError("SDL not built with rendering support");
   1.135 +    return NULL;
   1.136 +#endif
   1.137  }
   1.138  
   1.139  SDL_Renderer *
   1.140 @@ -330,6 +328,25 @@
   1.141      return 0;
   1.142  }
   1.143  
   1.144 +int
   1.145 +SDL_GetRendererOutputSize(SDL_Renderer * renderer, int *w, int *h)
   1.146 +{
   1.147 +    CHECK_RENDERER_MAGIC(renderer, -1);
   1.148 +
   1.149 +    if (renderer->target) {
   1.150 +        return SDL_QueryTexture(renderer->target, NULL, NULL, w, h);
   1.151 +    } else if (renderer->window) {
   1.152 +        SDL_GetWindowSize(renderer->window, w, h);
   1.153 +        return 0;
   1.154 +    } else if (renderer->GetOutputSize) {
   1.155 +        return renderer->GetOutputSize(renderer, w, h);
   1.156 +    } else {
   1.157 +        /* This should never happen */
   1.158 +        SDL_SetError("Renderer doesn't support querying output size");
   1.159 +        return -1;
   1.160 +    }
   1.161 +}
   1.162 +
   1.163  static SDL_bool
   1.164  IsSupportedFormat(SDL_Renderer * renderer, Uint32 format)
   1.165  {
   1.166 @@ -757,6 +774,13 @@
   1.167  
   1.168      CHECK_TEXTURE_MAGIC(texture, -1);
   1.169  
   1.170 +    if (!pixels) {
   1.171 +        return SDL_InvalidParamError("pixels");
   1.172 +    }
   1.173 +    if (!pitch) {
   1.174 +        return SDL_InvalidParamError("pitch");
   1.175 +    }
   1.176 +
   1.177      if (!rect) {
   1.178          full_rect.x = 0;
   1.179          full_rect.y = 0;
   1.180 @@ -925,6 +949,7 @@
   1.181      if (texture && !renderer->target) {
   1.182          /* Make a backup of the viewport */
   1.183          renderer->viewport_backup = renderer->viewport;
   1.184 +        renderer->clip_rect_backup = renderer->clip_rect;
   1.185          renderer->scale_backup = renderer->scale;
   1.186          renderer->logical_w_backup = renderer->logical_w;
   1.187          renderer->logical_h_backup = renderer->logical_h;
   1.188 @@ -942,10 +967,11 @@
   1.189          renderer->viewport.h = texture->h;
   1.190          renderer->scale.x = 1.0f;
   1.191          renderer->scale.y = 1.0f;
   1.192 -        renderer->logical_w = 0;
   1.193 -        renderer->logical_h = 0;
   1.194 +        renderer->logical_w = texture->w;
   1.195 +        renderer->logical_h = texture->h;
   1.196      } else {
   1.197          renderer->viewport = renderer->viewport_backup;
   1.198 +        renderer->clip_rect = renderer->clip_rect_backup;
   1.199          renderer->scale = renderer->scale_backup;
   1.200          renderer->logical_w = renderer->logical_w_backup;
   1.201          renderer->logical_h = renderer->logical_h_backup;
   1.202 @@ -953,6 +979,9 @@
   1.203      if (renderer->UpdateViewport(renderer) < 0) {
   1.204          return -1;
   1.205      }
   1.206 +    if (renderer->UpdateClipRect(renderer) < 0) {
   1.207 +        return -1;
   1.208 +    }
   1.209  
   1.210      /* All set! */
   1.211      return 0;
   1.212 @@ -973,13 +1002,8 @@
   1.213      float scale;
   1.214      SDL_Rect viewport;
   1.215  
   1.216 -    if (renderer->target) {
   1.217 -        SDL_QueryTexture(renderer->target, NULL, NULL, &w, &h);
   1.218 -    } else if (renderer->window) {
   1.219 -        SDL_GetWindowSize(renderer->window, &w, &h);
   1.220 -    } else {
   1.221 -        /* FIXME */
   1.222 -        return SDL_SetError("Internal error: No way to get output resolution");
   1.223 +    if (SDL_GetRendererOutputSize(renderer, &w, &h) < 0) {
   1.224 +        return -1;
   1.225      }
   1.226  
   1.227      want_aspect = (float)renderer->logical_w / renderer->logical_h;
   1.228 @@ -1062,16 +1086,8 @@
   1.229      } else {
   1.230          renderer->viewport.x = 0;
   1.231          renderer->viewport.y = 0;
   1.232 -        if (renderer->target) {
   1.233 -            SDL_QueryTexture(renderer->target, NULL, NULL,
   1.234 -                              &renderer->viewport.w, &renderer->viewport.h);
   1.235 -        } else if (renderer->window) {
   1.236 -            SDL_GetWindowSize(renderer->window,
   1.237 -                              &renderer->viewport.w, &renderer->viewport.h);
   1.238 -        } else {
   1.239 -            /* This will be filled in by UpdateViewport() */
   1.240 -            renderer->viewport.w = 0;
   1.241 -            renderer->viewport.h = 0;
   1.242 +        if (SDL_GetRendererOutputSize(renderer, &renderer->viewport.w, &renderer->viewport.h) < 0) {
   1.243 +            return -1;
   1.244          }
   1.245      }
   1.246      return renderer->UpdateViewport(renderer);
   1.247 @@ -1091,6 +1107,35 @@
   1.248  }
   1.249  
   1.250  int
   1.251 +SDL_RenderSetClipRect(SDL_Renderer * renderer, const SDL_Rect * rect)
   1.252 +{
   1.253 +    CHECK_RENDERER_MAGIC(renderer, -1)
   1.254 +
   1.255 +    if (rect) {
   1.256 +        renderer->clip_rect.x = (int)SDL_floor(rect->x * renderer->scale.x);
   1.257 +        renderer->clip_rect.y = (int)SDL_floor(rect->y * renderer->scale.y);
   1.258 +        renderer->clip_rect.w = (int)SDL_ceil(rect->w * renderer->scale.x);
   1.259 +        renderer->clip_rect.h = (int)SDL_ceil(rect->h * renderer->scale.y);
   1.260 +    } else {
   1.261 +        SDL_zero(renderer->clip_rect);
   1.262 +    }
   1.263 +    return renderer->UpdateClipRect(renderer);
   1.264 +}
   1.265 +
   1.266 +void
   1.267 +SDL_RenderGetClipRect(SDL_Renderer * renderer, SDL_Rect * rect)
   1.268 +{
   1.269 +    CHECK_RENDERER_MAGIC(renderer, )
   1.270 +
   1.271 +    if (rect) {
   1.272 +        rect->x = (int)(renderer->clip_rect.x / renderer->scale.x);
   1.273 +        rect->y = (int)(renderer->clip_rect.y / renderer->scale.y);
   1.274 +        rect->w = (int)(renderer->clip_rect.w / renderer->scale.x);
   1.275 +        rect->h = (int)(renderer->clip_rect.h / renderer->scale.y);
   1.276 +    }
   1.277 +}
   1.278 +
   1.279 +int
   1.280  SDL_RenderSetScale(SDL_Renderer * renderer, float scaleX, float scaleY)
   1.281  {
   1.282      CHECK_RENDERER_MAGIC(renderer, -1);
   1.283 @@ -1422,7 +1467,7 @@
   1.284  int
   1.285  SDL_RenderFillRect(SDL_Renderer * renderer, const SDL_Rect * rect)
   1.286  {
   1.287 -    SDL_Rect full_rect;
   1.288 +    SDL_Rect full_rect = { 0, 0, 0, 0 };
   1.289  
   1.290      CHECK_RENDERER_MAGIC(renderer, -1);
   1.291  
   1.292 @@ -1504,22 +1549,10 @@
   1.293      real_dstrect.x = 0;
   1.294      real_dstrect.y = 0;
   1.295      if (dstrect) {
   1.296 -        if (!SDL_IntersectRect(dstrect, &real_dstrect, &real_dstrect)) {
   1.297 +        if (!SDL_HasIntersection(dstrect, &real_dstrect)) {
   1.298              return 0;
   1.299          }
   1.300 -        /* Clip srcrect by the same amount as dstrect was clipped */
   1.301 -        if (dstrect->w != real_dstrect.w) {
   1.302 -            int deltax = (real_dstrect.x - dstrect->x);
   1.303 -            int deltaw = (real_dstrect.w - dstrect->w);
   1.304 -            real_srcrect.x += (deltax * real_srcrect.w) / dstrect->w;
   1.305 -            real_srcrect.w += (deltaw * real_srcrect.w) / dstrect->w;
   1.306 -        }
   1.307 -        if (dstrect->h != real_dstrect.h) {
   1.308 -            int deltay = (real_dstrect.y - dstrect->y);
   1.309 -            int deltah = (real_dstrect.h - dstrect->h);
   1.310 -            real_srcrect.y += (deltay * real_srcrect.h) / dstrect->h;
   1.311 -            real_srcrect.h += (deltah * real_srcrect.h) / dstrect->h;
   1.312 -        }
   1.313 +        real_dstrect = *dstrect;
   1.314      }
   1.315  
   1.316      if (texture->native) {
   1.317 @@ -1560,7 +1593,7 @@
   1.318      if (!renderer->RenderCopyEx) {
   1.319          return SDL_SetError("Renderer does not support RenderCopyEx");
   1.320      }
   1.321 -    
   1.322 +
   1.323      real_srcrect.x = 0;
   1.324      real_srcrect.y = 0;
   1.325      real_srcrect.w = texture->w;
   1.326 @@ -1656,9 +1689,14 @@
   1.327      SDL_Renderer *renderer;
   1.328  
   1.329      CHECK_TEXTURE_MAGIC(texture, );
   1.330 +
   1.331 +    renderer = texture->renderer;
   1.332 +    if (texture == renderer->target) {
   1.333 +        SDL_SetRenderTarget(renderer, NULL);
   1.334 +    }
   1.335 +
   1.336      texture->magic = NULL;
   1.337  
   1.338 -    renderer = texture->renderer;
   1.339      if (texture->next) {
   1.340          texture->next->prev = texture->prev;
   1.341      }
   1.342 @@ -1711,11 +1749,13 @@
   1.343  
   1.344      CHECK_TEXTURE_MAGIC(texture, -1);
   1.345      renderer = texture->renderer;
   1.346 -    if (renderer && renderer->GL_BindTexture) {
   1.347 +    if (texture->native) {
   1.348 +        return SDL_GL_BindTexture(texture->native, texw, texh);
   1.349 +    } else if (renderer && renderer->GL_BindTexture) {
   1.350          return renderer->GL_BindTexture(renderer, texture, texw, texh);
   1.351 +    } else {
   1.352 +        return SDL_Unsupported();
   1.353      }
   1.354 -
   1.355 -    return SDL_Unsupported();
   1.356  }
   1.357  
   1.358  int SDL_GL_UnbindTexture(SDL_Texture *texture)