Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

Changed the concept of a render clip rect to a render viewport.

The render viewport is automatically re-centered when the window changes size, so applications that don't care will not have to handle recalculating their rendering coordinates.

Fixed API for drawing and filling multiple rectangles - the parameter should be an array of rects, not an array of pointers to rects.

Fixed API for updating window rects for consistency with other APIs - the order is pointer to array followed by count in array.
  • Loading branch information
slouken committed Feb 15, 2011
1 parent ea308dc commit 1e9e878d6180c39665aa1db37278f7cc220563ca
@@ -364,16 +364,23 @@ extern DECLSPEC int SDLCALL SDL_LockTexture(SDL_Texture * texture,
extern DECLSPEC void SDLCALL SDL_UnlockTexture(SDL_Texture * texture);

/**
* \brief Set the clipping rectangle for rendering on the current target
* \brief Set the drawing area for rendering on the current target.
*
* \param rect The rectangle to clip rendering to, or NULL to disable clipping.
* \param rect The rectangle representing the drawing area, or NULL to set the viewport to the entire target.
*
* 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.
* The x,y of the viewport rect represents the origin for rendering.
*
* \note When the window is resized, the current viewport is automatically
* centered within the new window size.
*/
extern DECLSPEC void SDLCALL SDL_RenderSetClipRect(SDL_Renderer * renderer,
const SDL_Rect * rect);
extern DECLSPEC int SDLCALL SDL_RenderSetViewport(SDL_Renderer * renderer,
const SDL_Rect * rect);

/**
* \brief Get the drawing area for the current target.
*/
extern DECLSPEC void SDLCALL SDL_RenderGetViewport(SDL_Renderer * renderer,
SDL_Rect * rect);

/**
* \brief Set the color used for drawing operations (Fill and Line).
@@ -434,6 +441,8 @@ extern DECLSPEC int SDLCALL SDL_GetRenderDrawBlendMode(SDL_Renderer * renderer,

/**
* \brief Clear the current rendering target with the drawing color
*
* This function clears the entire rendering target, ignoring the viewport.
*/
extern DECLSPEC int SDLCALL SDL_RenderClear(SDL_Renderer * renderer);

@@ -504,7 +513,7 @@ extern DECLSPEC int SDLCALL SDL_RenderDrawRect(SDL_Renderer * renderer,
* \return 0 on success, or -1 on error
*/
extern DECLSPEC int SDLCALL SDL_RenderDrawRects(SDL_Renderer * renderer,
const SDL_Rect ** rects,
const SDL_Rect * rects,
int count);

/**
@@ -527,7 +536,7 @@ extern DECLSPEC int SDLCALL SDL_RenderFillRect(SDL_Renderer * renderer,
* \return 0 on success, or -1 on error
*/
extern DECLSPEC int SDLCALL SDL_RenderFillRects(SDL_Renderer * renderer,
const SDL_Rect ** rect,
const SDL_Rect * rect,
int count);

/**
@@ -374,7 +374,7 @@ extern DECLSPEC int SDLCALL SDL_ConvertPixels(int width, int height,
extern DECLSPEC int SDLCALL SDL_FillRect
(SDL_Surface * dst, const SDL_Rect * rect, Uint32 color);
extern DECLSPEC int SDLCALL SDL_FillRects
(SDL_Surface * dst, const SDL_Rect ** rects, int count, Uint32 color);
(SDL_Surface * dst, const SDL_Rect * rects, int count, Uint32 color);

/**
* Performs a fast blit from the source surface to the destination surface.
@@ -581,8 +581,8 @@ extern DECLSPEC int SDLCALL SDL_UpdateWindowSurface(SDL_Window * window);
* \sa SDL_UpdateWindowSurfaceRect()
*/
extern DECLSPEC int SDLCALL SDL_UpdateWindowSurfaceRects(SDL_Window * window,
int numrects,
SDL_Rect * rects);
SDL_Rect * rects,
int numrects);

/**
* \brief Set a window's input grab mode.
@@ -785,10 +785,10 @@ SDL_UpdateRects(SDL_Surface * screen, int numrects, SDL_Rect * rects)
stackrect->w = rect->w;
stackrect->h = rect->h;
}
SDL_UpdateWindowSurfaceRects(SDL_VideoWindow, numrects, stackrects);
SDL_UpdateWindowSurfaceRects(SDL_VideoWindow, stackrects, numrects);
SDL_stack_free(stackrects);
} else {
SDL_UpdateWindowSurfaceRects(SDL_VideoWindow, numrects, rects);
SDL_UpdateWindowSurfaceRects(SDL_VideoWindow, rects, numrects);
}
}
}
100 src/render/SDL_render.c 100644 → 100755
@@ -89,10 +89,25 @@ SDL_RendererEventWatch(void *userdata, SDL_Event *event)
{
SDL_Renderer *renderer = (SDL_Renderer *)userdata;

if (event->type == SDL_WINDOWEVENT && renderer->WindowEvent) {
if (event->type == SDL_WINDOWEVENT) {
SDL_Window *window = SDL_GetWindowFromID(event->window.windowID);
if (window == renderer->window) {
renderer->WindowEvent(renderer, &event->window);
if (renderer->WindowEvent) {
renderer->WindowEvent(renderer, &event->window);
}

if (event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
/* Try to keep the previous viewport centered */
int w, h;
SDL_Rect viewport;

SDL_GetWindowSize(window, &w, &h);
viewport.x = (w - renderer->viewport.w) / 2;
viewport.y = (h - renderer->viewport.h) / 2;
viewport.w = renderer->viewport.w;
viewport.h = renderer->viewport.h;
SDL_RenderSetViewport(renderer, &viewport);
}
}
}
return 0;
@@ -160,6 +175,8 @@ SDL_CreateRenderer(SDL_Window * window, int index, Uint32 flags)
renderer->magic = &renderer_magic;
renderer->window = window;

SDL_RenderSetViewport(renderer, NULL);

SDL_AddEventWatch(SDL_RendererEventWatch, renderer);

SDL_LogInfo(SDL_LOG_CATEGORY_RENDER,
@@ -172,7 +189,16 @@ SDL_Renderer *
SDL_CreateSoftwareRenderer(SDL_Surface * surface)
{
#if !SDL_RENDER_DISABLED
return SW_CreateRendererForSurface(surface);
SDL_Renderer *renderer;

renderer = SW_CreateRendererForSurface(surface);

if (renderer) {
renderer->magic = &renderer_magic;

SDL_RenderSetViewport(renderer, NULL);
}
return renderer;
#else
SDL_SetError("SDL not built with rendering support");
return NULL;
@@ -342,12 +368,13 @@ SDL_CreateTextureFromSurface(SDL_Renderer * renderer, SDL_Surface * surface)
SDL_UpdateTexture(texture, NULL, surface->pixels, surface->pitch);
}
} else {
SDL_PixelFormat dst_fmt;
SDL_PixelFormat *dst_fmt;
SDL_Surface *temp = NULL;

/* Set up a destination surface for the texture update */
SDL_InitFormat(&dst_fmt, format);
temp = SDL_ConvertSurface(surface, &dst_fmt, 0);
dst_fmt = SDL_AllocFormat(format);
temp = SDL_ConvertSurface(surface, dst_fmt, 0);
SDL_FreeFormat(dst_fmt);
if (temp) {
SDL_UpdateTexture(texture, NULL, temp->pixels, temp->pitch);
SDL_FreeSurface(temp);
@@ -733,12 +760,34 @@ SDL_UnlockTexture(SDL_Texture * texture)
}
}

int
SDL_RenderSetViewport(SDL_Renderer * renderer, const SDL_Rect * rect)
{
CHECK_RENDERER_MAGIC(renderer, -1);

if (rect) {
renderer->viewport = *rect;
} else {
renderer->viewport.x = 0;
renderer->viewport.y = 0;
if (renderer->window) {
SDL_GetWindowSize(renderer->window,
&renderer->viewport.w, &renderer->viewport.h);
} else {
/* This will be filled in by UpdateViewport() */
renderer->viewport.w = 0;
renderer->viewport.h = 0;
}
}
return renderer->UpdateViewport(renderer);
}

void
SDL_RenderSetClipRect(SDL_Renderer * renderer, const SDL_Rect * rect)
SDL_RenderGetViewport(SDL_Renderer * renderer, SDL_Rect * rect)
{
CHECK_RENDERER_MAGIC(renderer, );

renderer->SetClipRect(renderer, rect);
*rect = renderer->viewport;
}

int
@@ -884,7 +933,8 @@ SDL_RenderDrawRect(SDL_Renderer * renderer, const SDL_Rect * rect)

full_rect.x = 0;
full_rect.y = 0;
SDL_GetWindowSize(window, &full_rect.w, &full_rect.h);
full_rect.w = renderer->viewport.w;
full_rect.h = renderer->viewport.h;
rect = &full_rect;
}

@@ -903,7 +953,7 @@ SDL_RenderDrawRect(SDL_Renderer * renderer, const SDL_Rect * rect)

int
SDL_RenderDrawRects(SDL_Renderer * renderer,
const SDL_Rect ** rects, int count)
const SDL_Rect * rects, int count)
{
int i;

@@ -917,9 +967,8 @@ SDL_RenderDrawRects(SDL_Renderer * renderer,
return 0;
}

/* Check for NULL rect, which means fill entire window */
for (i = 0; i < count; ++i) {
if (SDL_RenderDrawRect(renderer, rects[i]) < 0) {
if (SDL_RenderDrawRect(renderer, &rects[i]) < 0) {
return -1;
}
}
@@ -929,15 +978,13 @@ SDL_RenderDrawRects(SDL_Renderer * renderer,
int
SDL_RenderFillRect(SDL_Renderer * renderer, const SDL_Rect * rect)
{
return SDL_RenderFillRects(renderer, &rect, 1);
return SDL_RenderFillRects(renderer, rect, 1);
}

int
SDL_RenderFillRects(SDL_Renderer * renderer,
const SDL_Rect ** rects, int count)
const SDL_Rect * rects, int count)
{
int i;

CHECK_RENDERER_MAGIC(renderer, -1);

if (!rects) {
@@ -947,21 +994,6 @@ SDL_RenderFillRects(SDL_Renderer * renderer,
if (count < 1) {
return 0;
}

/* Check for NULL rect, which means fill entire window */
for (i = 0; i < count; ++i) {
if (rects[i] == NULL) {
SDL_Window *window = renderer->window;
SDL_Rect full_rect;
const SDL_Rect *rect;

full_rect.x = 0;
full_rect.y = 0;
SDL_GetWindowSize(window, &full_rect.w, &full_rect.h);
rect = &full_rect;
return renderer->RenderFillRects(renderer, &rect, 1);
}
}
return renderer->RenderFillRects(renderer, rects, count);
}

@@ -994,7 +1026,8 @@ SDL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,

real_dstrect.x = 0;
real_dstrect.y = 0;
SDL_GetWindowSize(window, &real_dstrect.w, &real_dstrect.h);
real_dstrect.w = renderer->viewport.w;
real_dstrect.h = renderer->viewport.h;
if (dstrect) {
if (!SDL_IntersectRect(dstrect, &real_dstrect, &real_dstrect)) {
return 0;
@@ -1043,7 +1076,8 @@ SDL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,

real_rect.x = 0;
real_rect.y = 0;
SDL_GetWindowSize(window, &real_rect.w, &real_rect.h);
real_rect.w = renderer->viewport.w;
real_rect.h = renderer->viewport.h;
if (rect) {
if (!SDL_IntersectRect(rect, &real_rect, &real_rect)) {
return 0;
@@ -78,13 +78,13 @@ struct SDL_Renderer
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 (*UpdateViewport) (SDL_Renderer * renderer);
int (*RenderClear) (SDL_Renderer * renderer);
int (*RenderDrawPoints) (SDL_Renderer * renderer, const SDL_Point * points,
int count);
int (*RenderDrawLines) (SDL_Renderer * renderer, const SDL_Point * points,
int count);
int (*RenderFillRects) (SDL_Renderer * renderer, const SDL_Rect ** rects,
int (*RenderFillRects) (SDL_Renderer * renderer, const SDL_Rect * rects,
int count);
int (*RenderCopy) (SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * srcrect, const SDL_Rect * dstrect);
@@ -101,6 +101,9 @@ struct SDL_Renderer
/* The window associated with the renderer */
SDL_Window *window;

/* The drawable area within the window */
SDL_Rect viewport;

/* The list of textures */
SDL_Texture *textures;

0 comments on commit 1e9e878

Please sign in to comment.