Fixed bug 1622 - SDL_RenderSetViewport with empty SDL_Rect raises wrong error for OpenGL rendering backend
It's now legal to set an empty viewport rect - it will prevent any rendering. Also added an API to query the output size: SDL_GetRendererOutputSize()
This commit is contained in:
parent
b337b40e33
commit
c55f53aa40
8 changed files with 103 additions and 64 deletions
|
@ -211,6 +211,12 @@ extern DECLSPEC SDL_Renderer * SDLCALL SDL_GetRenderer(SDL_Window * window);
|
||||||
extern DECLSPEC int SDLCALL SDL_GetRendererInfo(SDL_Renderer * renderer,
|
extern DECLSPEC int SDLCALL SDL_GetRendererInfo(SDL_Renderer * renderer,
|
||||||
SDL_RendererInfo * info);
|
SDL_RendererInfo * info);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Get the output size of a rendering context.
|
||||||
|
*/
|
||||||
|
extern DECLSPEC int SDLCALL SDL_GetRendererOutputSize(SDL_Renderer * renderer,
|
||||||
|
int *w, int *h);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Create a texture for a rendering context.
|
* \brief Create a texture for a rendering context.
|
||||||
*
|
*
|
||||||
|
|
|
@ -337,6 +337,25 @@ SDL_GetRendererInfo(SDL_Renderer * renderer, SDL_RendererInfo * info)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
SDL_GetRendererOutputSize(SDL_Renderer * renderer, int *w, int *h)
|
||||||
|
{
|
||||||
|
CHECK_RENDERER_MAGIC(renderer, -1);
|
||||||
|
|
||||||
|
if (renderer->target) {
|
||||||
|
return SDL_QueryTexture(renderer->target, NULL, NULL, w, h);
|
||||||
|
} else if (renderer->window) {
|
||||||
|
SDL_GetWindowSize(renderer->window, w, h);
|
||||||
|
return 0;
|
||||||
|
} else if (renderer->GetOutputSize) {
|
||||||
|
return renderer->GetOutputSize(renderer, w, h);
|
||||||
|
} else {
|
||||||
|
/* This should never happen */
|
||||||
|
SDL_SetError("Renderer doesn't support querying output size");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static SDL_bool
|
static SDL_bool
|
||||||
IsSupportedFormat(SDL_Renderer * renderer, Uint32 format)
|
IsSupportedFormat(SDL_Renderer * renderer, Uint32 format)
|
||||||
{
|
{
|
||||||
|
@ -985,13 +1004,8 @@ UpdateLogicalSize(SDL_Renderer *renderer)
|
||||||
float scale;
|
float scale;
|
||||||
SDL_Rect viewport;
|
SDL_Rect viewport;
|
||||||
|
|
||||||
if (renderer->target) {
|
if (SDL_GetRendererOutputSize(renderer, &w, &h) < 0) {
|
||||||
SDL_QueryTexture(renderer->target, NULL, NULL, &w, &h);
|
return -1;
|
||||||
} else if (renderer->window) {
|
|
||||||
SDL_GetWindowSize(renderer->window, &w, &h);
|
|
||||||
} else {
|
|
||||||
/* FIXME */
|
|
||||||
return SDL_SetError("Internal error: No way to get output resolution");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
want_aspect = (float)renderer->logical_w / renderer->logical_h;
|
want_aspect = (float)renderer->logical_w / renderer->logical_h;
|
||||||
|
@ -1074,16 +1088,8 @@ SDL_RenderSetViewport(SDL_Renderer * renderer, const SDL_Rect * rect)
|
||||||
} else {
|
} else {
|
||||||
renderer->viewport.x = 0;
|
renderer->viewport.x = 0;
|
||||||
renderer->viewport.y = 0;
|
renderer->viewport.y = 0;
|
||||||
if (renderer->target) {
|
if (SDL_GetRendererOutputSize(renderer, &renderer->viewport.w, &renderer->viewport.h) < 0) {
|
||||||
SDL_QueryTexture(renderer->target, NULL, NULL,
|
return -1;
|
||||||
&renderer->viewport.w, &renderer->viewport.h);
|
|
||||||
} else 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);
|
return renderer->UpdateViewport(renderer);
|
||||||
|
|
|
@ -78,6 +78,7 @@ struct SDL_Renderer
|
||||||
const void *magic;
|
const void *magic;
|
||||||
|
|
||||||
void (*WindowEvent) (SDL_Renderer * renderer, const SDL_WindowEvent *event);
|
void (*WindowEvent) (SDL_Renderer * renderer, const SDL_WindowEvent *event);
|
||||||
|
int (*GetOutputSize) (SDL_Renderer * renderer, int *w, int *h);
|
||||||
int (*CreateTexture) (SDL_Renderer * renderer, SDL_Texture * texture);
|
int (*CreateTexture) (SDL_Renderer * renderer, SDL_Texture * texture);
|
||||||
int (*SetTextureColorMod) (SDL_Renderer * renderer,
|
int (*SetTextureColorMod) (SDL_Renderer * renderer,
|
||||||
SDL_Texture * texture);
|
SDL_Texture * texture);
|
||||||
|
|
|
@ -866,23 +866,25 @@ D3D_UpdateViewport(SDL_Renderer * renderer)
|
||||||
IDirect3DDevice9_SetViewport(data->device, &viewport);
|
IDirect3DDevice9_SetViewport(data->device, &viewport);
|
||||||
|
|
||||||
/* Set an orthographic projection matrix */
|
/* Set an orthographic projection matrix */
|
||||||
matrix.m[0][0] = 2.0f / renderer->viewport.w;
|
if (renderer->viewport.w && renderer->viewport.h) {
|
||||||
matrix.m[0][1] = 0.0f;
|
matrix.m[0][0] = 2.0f / renderer->viewport.w;
|
||||||
matrix.m[0][2] = 0.0f;
|
matrix.m[0][1] = 0.0f;
|
||||||
matrix.m[0][3] = 0.0f;
|
matrix.m[0][2] = 0.0f;
|
||||||
matrix.m[1][0] = 0.0f;
|
matrix.m[0][3] = 0.0f;
|
||||||
matrix.m[1][1] = -2.0f / renderer->viewport.h;
|
matrix.m[1][0] = 0.0f;
|
||||||
matrix.m[1][2] = 0.0f;
|
matrix.m[1][1] = -2.0f / renderer->viewport.h;
|
||||||
matrix.m[1][3] = 0.0f;
|
matrix.m[1][2] = 0.0f;
|
||||||
matrix.m[2][0] = 0.0f;
|
matrix.m[1][3] = 0.0f;
|
||||||
matrix.m[2][1] = 0.0f;
|
matrix.m[2][0] = 0.0f;
|
||||||
matrix.m[2][2] = 1.0f;
|
matrix.m[2][1] = 0.0f;
|
||||||
matrix.m[2][3] = 0.0f;
|
matrix.m[2][2] = 1.0f;
|
||||||
matrix.m[3][0] = -1.0f;
|
matrix.m[2][3] = 0.0f;
|
||||||
matrix.m[3][1] = 1.0f;
|
matrix.m[3][0] = -1.0f;
|
||||||
matrix.m[3][2] = 0.0f;
|
matrix.m[3][1] = 1.0f;
|
||||||
matrix.m[3][3] = 1.0f;
|
matrix.m[3][2] = 0.0f;
|
||||||
IDirect3DDevice9_SetTransform(data->device, D3DTS_PROJECTION, &matrix);
|
matrix.m[3][3] = 1.0f;
|
||||||
|
IDirect3DDevice9_SetTransform(data->device, D3DTS_PROJECTION, &matrix);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -849,28 +849,25 @@ GL_UpdateViewport(SDL_Renderer * renderer)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!renderer->viewport.w || !renderer->viewport.h) {
|
|
||||||
/* The viewport isn't set up yet, ignore it */
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
data->glViewport(renderer->viewport.x, renderer->viewport.y,
|
data->glViewport(renderer->viewport.x, renderer->viewport.y,
|
||||||
renderer->viewport.w, renderer->viewport.h);
|
renderer->viewport.w, renderer->viewport.h);
|
||||||
|
|
||||||
data->glMatrixMode(GL_PROJECTION);
|
data->glMatrixMode(GL_PROJECTION);
|
||||||
data->glLoadIdentity();
|
data->glLoadIdentity();
|
||||||
if (renderer->target) {
|
if (renderer->viewport.w && renderer->viewport.h) {
|
||||||
data->glOrtho((GLdouble) 0,
|
if (renderer->target) {
|
||||||
(GLdouble) renderer->viewport.w,
|
data->glOrtho((GLdouble) 0,
|
||||||
(GLdouble) 0,
|
(GLdouble) renderer->viewport.w,
|
||||||
(GLdouble) renderer->viewport.h,
|
(GLdouble) 0,
|
||||||
0.0, 1.0);
|
(GLdouble) renderer->viewport.h,
|
||||||
} else {
|
0.0, 1.0);
|
||||||
data->glOrtho((GLdouble) 0,
|
} else {
|
||||||
(GLdouble) renderer->viewport.w,
|
data->glOrtho((GLdouble) 0,
|
||||||
(GLdouble) renderer->viewport.h,
|
(GLdouble) renderer->viewport.w,
|
||||||
(GLdouble) 0,
|
(GLdouble) renderer->viewport.h,
|
||||||
0.0, 1.0);
|
(GLdouble) 0,
|
||||||
|
0.0, 1.0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return GL_CheckError("", renderer);
|
return GL_CheckError("", renderer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -623,12 +623,14 @@ GLES_UpdateViewport(SDL_Renderer * renderer)
|
||||||
data->glViewport(renderer->viewport.x, renderer->viewport.y,
|
data->glViewport(renderer->viewport.x, renderer->viewport.y,
|
||||||
renderer->viewport.w, renderer->viewport.h);
|
renderer->viewport.w, renderer->viewport.h);
|
||||||
|
|
||||||
data->glMatrixMode(GL_PROJECTION);
|
if (renderer->viewport.w && renderer->viewport.h) {
|
||||||
data->glLoadIdentity();
|
data->glMatrixMode(GL_PROJECTION);
|
||||||
data->glOrthof((GLfloat) 0,
|
data->glLoadIdentity();
|
||||||
(GLfloat) renderer->viewport.w,
|
data->glOrthof((GLfloat) 0,
|
||||||
(GLfloat) renderer->viewport.h,
|
(GLfloat) renderer->viewport.w,
|
||||||
(GLfloat) 0, 0.0, 1.0);
|
(GLfloat) renderer->viewport.h,
|
||||||
|
(GLfloat) 0, 0.0, 1.0);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -906,6 +906,10 @@ GLES2_SetOrthographicProjection(SDL_Renderer *renderer)
|
||||||
GLfloat projection[4][4];
|
GLfloat projection[4][4];
|
||||||
GLuint locProjection;
|
GLuint locProjection;
|
||||||
|
|
||||||
|
if (!renderer->viewport.w || !renderer->viewport.h) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Prepare an orthographic projection */
|
/* Prepare an orthographic projection */
|
||||||
projection[0][0] = 2.0f / renderer->viewport.w;
|
projection[0][0] = 2.0f / renderer->viewport.w;
|
||||||
projection[0][1] = 0.0f;
|
projection[0][1] = 0.0f;
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
static SDL_Renderer *SW_CreateRenderer(SDL_Window * window, Uint32 flags);
|
static SDL_Renderer *SW_CreateRenderer(SDL_Window * window, Uint32 flags);
|
||||||
static void SW_WindowEvent(SDL_Renderer * renderer,
|
static void SW_WindowEvent(SDL_Renderer * renderer,
|
||||||
const SDL_WindowEvent *event);
|
const SDL_WindowEvent *event);
|
||||||
|
static int SW_GetOutputSize(SDL_Renderer * renderer, int *w, int *h);
|
||||||
static int SW_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
|
static int SW_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
|
||||||
static int SW_SetTextureColorMod(SDL_Renderer * renderer,
|
static int SW_SetTextureColorMod(SDL_Renderer * renderer,
|
||||||
SDL_Texture * texture);
|
SDL_Texture * texture);
|
||||||
|
@ -110,9 +111,14 @@ SW_ActivateRenderer(SDL_Renderer * renderer)
|
||||||
data->surface = data->window;
|
data->surface = data->window;
|
||||||
}
|
}
|
||||||
if (!data->surface) {
|
if (!data->surface) {
|
||||||
data->surface = data->window = SDL_GetWindowSurface(renderer->window);
|
SDL_Surface *surface = SDL_GetWindowSurface(renderer->window);
|
||||||
|
if (surface) {
|
||||||
|
data->surface = data->window = surface;
|
||||||
|
renderer->viewport.w = surface->w;
|
||||||
|
renderer->viewport.h = surface->h;
|
||||||
|
|
||||||
SW_UpdateViewport(renderer);
|
SW_UpdateViewport(renderer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return data->surface;
|
return data->surface;
|
||||||
}
|
}
|
||||||
|
@ -143,6 +149,7 @@ SW_CreateRendererForSurface(SDL_Surface * surface)
|
||||||
data->surface = surface;
|
data->surface = surface;
|
||||||
|
|
||||||
renderer->WindowEvent = SW_WindowEvent;
|
renderer->WindowEvent = SW_WindowEvent;
|
||||||
|
renderer->GetOutputSize = SW_GetOutputSize;
|
||||||
renderer->CreateTexture = SW_CreateTexture;
|
renderer->CreateTexture = SW_CreateTexture;
|
||||||
renderer->SetTextureColorMod = SW_SetTextureColorMod;
|
renderer->SetTextureColorMod = SW_SetTextureColorMod;
|
||||||
renderer->SetTextureAlphaMod = SW_SetTextureAlphaMod;
|
renderer->SetTextureAlphaMod = SW_SetTextureAlphaMod;
|
||||||
|
@ -194,6 +201,25 @@ SW_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
SW_GetOutputSize(SDL_Renderer * renderer, int *w, int *h)
|
||||||
|
{
|
||||||
|
SDL_Surface *surface = SW_ActivateRenderer(renderer);
|
||||||
|
|
||||||
|
if (surface) {
|
||||||
|
if (w) {
|
||||||
|
*w = surface->w;
|
||||||
|
}
|
||||||
|
if (h) {
|
||||||
|
*h = surface->h;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
SDL_SetError("Software renderer doesn't have an output surface");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
SW_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
SW_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||||
{
|
{
|
||||||
|
@ -313,11 +339,6 @@ SW_UpdateViewport(SDL_Renderer * renderer)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!renderer->viewport.w && !renderer->viewport.h) {
|
|
||||||
/* There may be no window, so update the viewport directly */
|
|
||||||
renderer->viewport.w = surface->w;
|
|
||||||
renderer->viewport.h = surface->h;
|
|
||||||
}
|
|
||||||
SDL_SetClipRect(data->surface, &renderer->viewport);
|
SDL_SetClipRect(data->surface, &renderer->viewport);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue