Reorganized the render target code, moving the viewport handling to the general code and adding software implementation.
--- a/src/render/SDL_render.c Sat Jan 21 22:14:38 2012 -0500
+++ b/src/render/SDL_render.c Sat Jan 21 22:22:30 2012 -0500
@@ -106,11 +106,16 @@
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);
+ if (renderer->target) {
+ renderer->viewport_backup.x = (w - renderer->viewport_backup.w) / 2;
+ renderer->viewport_backup.y = (h - renderer->viewport_backup.h) / 2;
+ } else {
+ 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);
+ }
} else if (event->window.event == SDL_WINDOWEVENT_MINIMIZED) {
renderer->minimized = SDL_TRUE;
} else if (event->window.event == SDL_WINDOWEVENT_RESTORED) {
@@ -796,6 +801,72 @@
}
}
+SDL_bool
+SDL_RenderTargetSupported(SDL_Renderer *renderer)
+{
+ if (!renderer || !renderer->SetTargetTexture) {
+ return SDL_FALSE;
+ }
+ return (renderer->info.flags & SDL_RENDERER_TARGETTEXTURE) != 0;
+}
+
+int
+SDL_SetTargetTexture(SDL_Renderer *renderer, SDL_Texture *texture)
+{
+ SDL_Rect viewport;
+
+ if (!SDL_RenderTargetSupported(renderer)) {
+ SDL_Unsupported();
+ return -1;
+ }
+ if (texture == renderer->target) {
+ /* Nothing to do! */
+ return 0;
+ }
+
+ /* texture == NULL is valid and means reset the target to the window */
+ if (texture) {
+ CHECK_TEXTURE_MAGIC(texture, -1);
+ if (renderer != texture->renderer) {
+ SDL_SetError("Texture was not created with this renderer");
+ return -1;
+ }
+ if (!(texture->access & SDL_TEXTUREACCESS_TARGET)) {
+ SDL_SetError("Texture not created with SDL_TEXTUREACCESS_TARGET");
+ return -1;
+ }
+ if (texture->native) {
+ /* Always render to the native texture */
+ texture = texture->native;
+ }
+ }
+
+ if (texture && !renderer->target) {
+ /* Make a backup of the viewport */
+ renderer->viewport_backup = renderer->viewport;
+ }
+ renderer->target = texture;
+
+ if (renderer->SetTargetTexture(renderer, texture) < 0) {
+ return -1;
+ }
+
+ if (texture) {
+ viewport.x = 0;
+ viewport.y = 0;
+ viewport.w = texture->w;
+ viewport.h = texture->h;
+ } else {
+ viewport = renderer->viewport_backup;
+ }
+ if (SDL_RenderSetViewport(renderer, &viewport) < 0) {
+ return -1;
+ }
+
+ /* All set! */
+ return 0;
+}
+
int
SDL_RenderSetViewport(SDL_Renderer * renderer, const SDL_Rect * rect)
{
@@ -1150,35 +1221,6 @@
format, pixels, pitch);
}
-SDL_bool
-SDL_RenderTargetSupported(SDL_Renderer *renderer)
-{
- if (!renderer || !renderer->SetTargetTexture) {
- return SDL_FALSE;
- }
- return (renderer->info.flags & SDL_RENDERER_TARGETTEXTURE) != 0;
-}
-
-int
-SDL_SetTargetTexture(SDL_Renderer *renderer, SDL_Texture *texture)
-{
-
- if(!renderer) {
- return -1;
- }
- if (!renderer->SetTargetTexture) {
- SDL_Unsupported();
- return -1;
- }
- // Warning: texture==NULL is a valid parameter
- if( texture ) {
- CHECK_TEXTURE_MAGIC(texture, -1);
- if(renderer != texture->renderer) return -1;
- }
-
- return renderer->SetTargetTexture(renderer, texture);
-}
-
void
SDL_RenderPresent(SDL_Renderer * renderer)
{
--- a/src/render/SDL_sysrender.h Sat Jan 21 22:14:38 2012 -0500
+++ b/src/render/SDL_sysrender.h Sat Jan 21 22:22:30 2012 -0500
@@ -77,6 +77,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);
+ int (*SetTargetTexture) (SDL_Renderer * renderer, SDL_Texture * texture);
int (*UpdateViewport) (SDL_Renderer * renderer);
int (*RenderClear) (SDL_Renderer * renderer);
int (*RenderDrawPoints) (SDL_Renderer * renderer, const SDL_Point * points,
@@ -87,7 +88,6 @@
int count);
int (*RenderCopy) (SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * srcrect, const SDL_Rect * dstrect);
- int (*SetTargetTexture) (SDL_Renderer * renderer, SDL_Texture * texture);
int (*RenderReadPixels) (SDL_Renderer * renderer, const SDL_Rect * rect,
Uint32 format, void * pixels, int pitch);
void (*RenderPresent) (SDL_Renderer * renderer);
@@ -104,9 +104,11 @@
/* The drawable area within the window */
SDL_Rect viewport;
+ SDL_Rect viewport_backup;
/* The list of textures */
SDL_Texture *textures;
+ SDL_Texture *target;
Uint8 r, g, b, a; /**< Color for drawing operations values */
SDL_BlendMode blendMode; /**< The drawing blend mode */
--- a/src/render/direct3d/SDL_render_d3d.c Sat Jan 21 22:14:38 2012 -0500
+++ b/src/render/direct3d/SDL_render_d3d.c Sat Jan 21 22:22:30 2012 -0500
@@ -99,6 +99,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 int D3D_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture);
static int D3D_UpdateViewport(SDL_Renderer * renderer);
static int D3D_RenderClear(SDL_Renderer * renderer);
static int D3D_RenderDrawPoints(SDL_Renderer * renderer,
@@ -111,7 +112,6 @@
const SDL_Rect * srcrect, const SDL_Rect * dstrect);
static int D3D_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
Uint32 format, void * pixels, int pitch);
-static int D3D_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture);
static void D3D_RenderPresent(SDL_Renderer * renderer);
static void D3D_DestroyTexture(SDL_Renderer * renderer,
SDL_Texture * texture);
@@ -141,10 +141,6 @@
D3DTEXTUREFILTERTYPE scaleMode;
IDirect3DSurface9 *defaultRenderTarget;
IDirect3DSurface9 *currentRenderTarget;
- SDL_bool renderTargetActive;
- SDL_Rect viewport_copy;
-
- Uint32 NumSimultaneousRTs;
} D3D_RenderData;
typedef struct
@@ -392,6 +388,7 @@
renderer->UpdateTexture = D3D_UpdateTexture;
renderer->LockTexture = D3D_LockTexture;
renderer->UnlockTexture = D3D_UnlockTexture;
+ renderer->SetTargetTexture = D3D_SetTargetTexture;
renderer->UpdateViewport = D3D_UpdateViewport;
renderer->RenderClear = D3D_RenderClear;
renderer->RenderDrawPoints = D3D_RenderDrawPoints;
@@ -399,14 +396,13 @@
renderer->RenderFillRects = D3D_RenderFillRects;
renderer->RenderCopy = D3D_RenderCopy;
renderer->RenderReadPixels = D3D_RenderReadPixels;
- renderer->SetTargetTexture = D3D_SetTargetTexture;
renderer->RenderPresent = D3D_RenderPresent;
renderer->DestroyTexture = D3D_DestroyTexture;
renderer->DestroyRenderer = D3D_DestroyRenderer;
renderer->info = D3D_RenderDriver.info;
renderer->driverdata = data;
- renderer->info.flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE;
+ renderer->info.flags = SDL_RENDERER_ACCELERATED;
SDL_VERSION(&windowinfo.version);
SDL_GetWindowWMInfo(window, &windowinfo);
@@ -486,7 +482,9 @@
IDirect3DDevice9_GetDeviceCaps(data->device, &caps);
renderer->info.max_texture_width = caps.MaxTextureWidth;
renderer->info.max_texture_height = caps.MaxTextureHeight;
- data->NumSimultaneousRTs = caps.NumSimultaneousRTs;
+ if (caps.NumSimultaneousRTs >= 2) {
+ renderer->info.flags |= SDL_RENDERER_TARGETTEXTURE;
+ }
/* Set up parameters for rendering */
IDirect3DDevice9_SetVertexShader(data->device, NULL);
@@ -519,7 +517,6 @@
/* Store the default render target */
IDirect3DDevice9_GetRenderTarget(data->device, 0, &data->defaultRenderTarget );
data->currentRenderTarget = NULL;
- data->renderTargetActive = SDL_FALSE;
/* Set an identity world and view matrix */
matrix.m[0][0] = 1.0f;
@@ -569,79 +566,6 @@
}
static int
-D3D_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture)
-{
- D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
- D3D_TextureData *texturedata;
- D3DMATRIX matrix;
- HRESULT result;
-
- D3D_ActivateRenderer(renderer);
-
- if (data->NumSimultaneousRTs < 2) {
- SDL_Unsupported();
- return -1;
- }
-
- // Release the previous render target if it wasn't the default one
- if (data->currentRenderTarget != NULL) {
- IDirect3DSurface9_Release(data->currentRenderTarget);
- data->currentRenderTarget = NULL;
- }
-
- /* Prepare an identity world and view matrix */
- matrix.m[0][0] = 1.0f;
- matrix.m[0][1] = 0.0f;
- matrix.m[0][2] = 0.0f;
- matrix.m[0][3] = 0.0f;
- matrix.m[1][0] = 0.0f;
- matrix.m[1][1] = 1.0f;
- matrix.m[1][2] = 0.0f;
- matrix.m[1][3] = 0.0f;
- matrix.m[2][0] = 0.0f;
- matrix.m[2][1] = 0.0f;
- matrix.m[2][2] = 1.0f;
- matrix.m[2][3] = 0.0f;
- matrix.m[3][0] = 0.0f;
- matrix.m[3][1] = 0.0f;
- matrix.m[3][2] = 0.0f;
- matrix.m[3][3] = 1.0f;
-
- if (texture == NULL) {
- if (data->renderTargetActive) {
- data->renderTargetActive = SDL_FALSE;
- IDirect3DDevice9_SetRenderTarget(data->device, 0, data->defaultRenderTarget );
- renderer->viewport = data->viewport_copy;
- D3D_UpdateViewport(renderer);
- }
- return 0;
- }
- if (renderer != texture->renderer) return -1;
-
- if ( !data->renderTargetActive ) {
- data->viewport_copy = renderer->viewport;
- }
-
- texturedata = (D3D_TextureData *) texture->driverdata;
- result = IDirect3DTexture9_GetSurfaceLevel(texturedata->texture, 0, &data->currentRenderTarget );
- if(FAILED(result)) {
- return -1;
- }
- result = IDirect3DDevice9_SetRenderTarget(data->device, 0, data->currentRenderTarget );
- if(FAILED(result)) {
- return -1;
- }
-
- data->renderTargetActive = SDL_TRUE;
- renderer->viewport.x = 0;
- renderer->viewport.y = 0;
- renderer->viewport.w = texture->w;
- renderer->viewport.h = texture->h;
- D3D_UpdateViewport(renderer);
- return 0;
-}
-
-static int
D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
{
D3D_RenderData *renderdata = (D3D_RenderData *) renderer->driverdata;
@@ -668,11 +592,10 @@
} else
#endif
if (texture->access == SDL_TEXTUREACCESS_TARGET) {
- pool = D3DPOOL_DEFAULT; // D3DPOOL_MANAGED does not work with usage=D3DUSAGE_RENDERTARGET
+ /* D3DPOOL_MANAGED does not work with D3DUSAGE_RENDERTARGET */
+ pool = D3DPOOL_DEFAULT;
usage = D3DUSAGE_RENDERTARGET;
- }
- else
- {
+ } else {
pool = D3DPOOL_MANAGED;
usage = 0;
}
@@ -811,6 +734,41 @@
}
static int
+D3D_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+ D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
+ D3D_TextureData *texturedata;
+ HRESULT result;
+
+ D3D_ActivateRenderer(renderer);
+
+ /* Release the previous render target if it wasn't the default one */
+ if (data->currentRenderTarget != NULL) {
+ IDirect3DSurface9_Release(data->currentRenderTarget);
+ data->currentRenderTarget = NULL;
+ }
+
+ if (texture == NULL) {
+ IDirect3DDevice9_SetRenderTarget(data->device, 0, data->defaultRenderTarget);
+ return 0;
+ }
+
+ texturedata = (D3D_TextureData *) texture->driverdata;
+ result = IDirect3DTexture9_GetSurfaceLevel(texturedata->texture, 0, &data->currentRenderTarget);
+ if(FAILED(result)) {
+ D3D_SetError("GetSurfaceLevel()", result);
+ return -1;
+ }
+ result = IDirect3DDevice9_SetRenderTarget(data->device, 0, data->currentRenderTarget);
+ if(FAILED(result)) {
+ D3D_SetError("SetRenderTarget()", result);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
D3D_RenderClear(SDL_Renderer * renderer)
{
D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
--- a/src/render/opengl/SDL_render_gl.c Sat Jan 21 22:14:38 2012 -0500
+++ b/src/render/opengl/SDL_render_gl.c Sat Jan 21 22:22:30 2012 -0500
@@ -54,6 +54,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 int GL_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture);
static int GL_UpdateViewport(SDL_Renderer * renderer);
static int GL_RenderClear(SDL_Renderer * renderer);
static int GL_RenderDrawPoints(SDL_Renderer * renderer,
@@ -66,7 +67,6 @@
const SDL_Rect * srcrect, const SDL_Rect * dstrect);
static int GL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
Uint32 pixel_format, void * pixels, int pitch);
-static int GL_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture);
static void GL_RenderPresent(SDL_Renderer * renderer);
static void GL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture);
static void GL_DestroyRenderer(SDL_Renderer * renderer);
@@ -104,8 +104,6 @@
SDL_bool GL_EXT_framebuffer_object_supported;
GL_FBOList *framebuffers;
- SDL_Texture *renderTarget;
- SDL_Rect viewport_copy;
/* OpenGL functions */
#define SDL_PROC(ret,func,params) ret (APIENTRY *func) params;
@@ -309,19 +307,19 @@
renderer->UpdateTexture = GL_UpdateTexture;
renderer->LockTexture = GL_LockTexture;
renderer->UnlockTexture = GL_UnlockTexture;
+ renderer->SetTargetTexture = GL_SetTargetTexture;
renderer->UpdateViewport = GL_UpdateViewport;
renderer->RenderClear = GL_RenderClear;
renderer->RenderDrawPoints = GL_RenderDrawPoints;
renderer->RenderDrawLines = GL_RenderDrawLines;
renderer->RenderFillRects = GL_RenderFillRects;
renderer->RenderCopy = GL_RenderCopy;
- renderer->SetTargetTexture = GL_SetTargetTexture;
renderer->RenderReadPixels = GL_RenderReadPixels;
renderer->RenderPresent = GL_RenderPresent;
renderer->DestroyTexture = GL_DestroyTexture;
renderer->DestroyRenderer = GL_DestroyRenderer;
renderer->info = GL_RenderDriver.info;
- renderer->info.flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE;
+ renderer->info.flags = SDL_RENDERER_ACCELERATED;
renderer->driverdata = data;
renderer->window = window;
@@ -399,11 +397,11 @@
SDL_GL_GetProcAddress("glFramebufferTexture2DEXT");
data->glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC)
SDL_GL_GetProcAddress("glBindFramebufferEXT");
- data->glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)
+ data->glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)
SDL_GL_GetProcAddress("glCheckFramebufferStatusEXT");
+ renderer->info.flags |= SDL_RENDERER_TARGETTEXTURE;
}
data->framebuffers = NULL;
- data->renderTarget = NULL;
/* Set up parameters for rendering */
GL_ResetState(renderer);
@@ -466,74 +464,6 @@
}
static int
-GL_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture)
-{
- GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
-
- GL_TextureData *texturedata;
- GLenum status;
-
- if (!renderer) return -1;
- GL_ActivateRenderer(renderer);
-
- if (! data->GL_EXT_framebuffer_object_supported) {
- SDL_Unsupported();
- return -1;
- }
-
- if (texture == NULL) {
- if (data->renderTarget != NULL) {
- data->renderTarget = NULL;
- renderer->viewport = data->viewport_copy;
- data->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
- data->glMatrixMode(GL_PROJECTION);
- data->glLoadIdentity();
- data->glMatrixMode(GL_MODELVIEW);
- data->glLoadIdentity();
- data->glViewport(renderer->viewport.x, renderer->viewport.y, renderer->viewport.w, renderer->viewport.h);
- data->glOrtho(0.0, (GLdouble) renderer->viewport.w, (GLdouble) renderer->viewport.h, 0.0, 0.0, 1.0);
- }
- return 0;
- }
- if (renderer != texture->renderer) return -1;
- if (data->renderTarget==NULL) {
- // Keep a copy of the default viewport to restore when texture==NULL
- data->viewport_copy = renderer->viewport;
- }
-
-
- texturedata = (GL_TextureData *) texture->driverdata;
- if (!texturedata) {
- if (texture->native && texture->native->driverdata) {
- texture = texture->native;
- texturedata = texture->driverdata;
- }
- else return -1;
- }
- data->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, texturedata->fbo->FBO);
- /* TODO: check if texture pixel format allows this operation */
- data->glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, texturedata->type, texturedata->texture, 0);
- /* Check FBO status */
- status = data->glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
- if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
- return -1;
- }
-
- data->renderTarget = texture;
- renderer->viewport.x = 0;
- renderer->viewport.y = 0;
- renderer->viewport.w = texture->w;
- renderer->viewport.h = texture->h;
- data->glMatrixMode(GL_PROJECTION);
- data->glLoadIdentity();
- data->glOrtho(0.0, (GLdouble) texture->w, 0.0, (GLdouble) texture->h, 0.0, 1.0);
- data->glMatrixMode(GL_MODELVIEW);
- data->glLoadIdentity();
- data->glViewport(0, 0, texture->w, texture->h);
- return 0;
-}
-
-static int
GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
{
GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata;
@@ -777,6 +707,33 @@
}
static int
+GL_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+ GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
+ GL_TextureData *texturedata;
+ GLenum status;
+
+ GL_ActivateRenderer(renderer);
+
+ if (texture == NULL) {
+ data->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+ return 0;
+ }
+
+ texturedata = (GL_TextureData *) texture->driverdata;
+ data->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, texturedata->fbo->FBO);
+ /* TODO: check if texture pixel format allows this operation */
+ data->glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, texturedata->type, texturedata->texture, 0);
+ /* Check FBO status */
+ status = data->glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
+ if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
+ SDL_SetError("glFramebufferTexture2DEXT() failed");
+ return -1;
+ }
+ return 0;
+}
+
+static int
GL_UpdateViewport(SDL_Renderer * renderer)
{
GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
@@ -791,10 +748,19 @@
data->glMatrixMode(GL_PROJECTION);
data->glLoadIdentity();
- data->glOrtho((GLdouble) 0,
- (GLdouble) renderer->viewport.w,
- (GLdouble) renderer->viewport.h,
- (GLdouble) 0, 0.0, 1.0);
+ if (renderer->target) {
+ data->glOrtho((GLdouble) 0,
+ (GLdouble) renderer->viewport.w,
+ (GLdouble) 0,
+ (GLdouble) renderer->viewport.h,
+ 0.0, 1.0);
+ } else {
+ data->glOrtho((GLdouble) 0,
+ (GLdouble) renderer->viewport.w,
+ (GLdouble) renderer->viewport.h,
+ (GLdouble) 0,
+ 0.0, 1.0);
+ }
return 0;
}
--- a/src/render/opengles/SDL_render_gles.c Sat Jan 21 22:14:38 2012 -0500
+++ b/src/render/opengles/SDL_render_gles.c Sat Jan 21 22:22:30 2012 -0500
@@ -56,6 +56,8 @@
const SDL_Rect * rect, void **pixels, int *pitch);
static void GLES_UnlockTexture(SDL_Renderer * renderer,
SDL_Texture * texture);
+static int GLES_SetTargetTexture(SDL_Renderer * renderer,
+ SDL_Texture * texture);
static int GLES_UpdateViewport(SDL_Renderer * renderer);
static int GLES_RenderClear(SDL_Renderer * renderer);
static int GLES_RenderDrawPoints(SDL_Renderer * renderer,
@@ -73,7 +75,6 @@
static void GLES_DestroyTexture(SDL_Renderer * renderer,
SDL_Texture * texture);
static void GLES_DestroyRenderer(SDL_Renderer * renderer);
-static int GLES_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture);
typedef struct GLES_FBOList GLES_FBOList;
@@ -110,8 +111,6 @@
#undef SDL_PROC
SDL_bool GL_OES_framebuffer_object_supported;
GLES_FBOList *framebuffers;
- SDL_Texture *renderTarget;
- SDL_Rect viewport_copy;
SDL_bool useDrawTexture;
SDL_bool GL_OES_draw_texture_supported;
@@ -257,71 +256,6 @@
data->glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
-static int
-GLES_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture)
-{
- GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
- int w, h;
- GLES_TextureData *texturedata = NULL;
- GLenum status;
-
- if (!renderer) return -1;
- GLES_ActivateRenderer(renderer);
- if (! data->GL_OES_framebuffer_object_supported) {
- SDL_Unsupported();
- return -1;
- }
-
- if (texture == NULL) {
- if (data->renderTarget != NULL) {
- data->renderTarget = NULL;
- renderer->viewport = data->viewport_copy;
- data->glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
- data->glMatrixMode(GL_PROJECTION);
- data->glLoadIdentity();
- data->glMatrixMode(GL_MODELVIEW);
- data->glLoadIdentity();
- data->glViewport(renderer->viewport.x, renderer->viewport.y, renderer->viewport.w, renderer->viewport.h);
- data->glOrthof(0.0, (GLfloat) renderer->viewport.w, (GLfloat) renderer->viewport.h, 0.0, 0.0, 1.0);
- }
- return 0;
- }
-
- if (renderer != texture->renderer) return -1;
- if (data->renderTarget==NULL) {
- // Keep a copy of the default viewport to restore when texture==NULL
- data->viewport_copy = renderer->viewport;
- }
- texturedata = (GLES_TextureData *) texture->driverdata;
- if (!texturedata) {
- if (texture->native && texture->native->driverdata) {
- texture = texture->native;
- texturedata = texture->driverdata;
- }
- else return -1;
- }
- data->glBindFramebufferOES(GL_FRAMEBUFFER_OES, texturedata->fbo->FBO);
- /* TODO: check if texture pixel format allows this operation */
- data->glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, texturedata->type, texturedata->texture, 0);
- /* Check FBO status */
- status = data->glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
- if (status != GL_FRAMEBUFFER_COMPLETE_OES) {
- return -1;
- }
- data->renderTarget = texture;
- renderer->viewport.x = 0;
- renderer->viewport.y = 0;
- renderer->viewport.w = texture->w;
- renderer->viewport.h = texture->h;
- data->glMatrixMode(GL_PROJECTION);
- data->glLoadIdentity();
- data->glOrthof(0.0, (GLfloat) texture->w, 0.0, (GLfloat) texture->h, 0.0, 1.0);
- data->glMatrixMode(GL_MODELVIEW);
- data->glLoadIdentity();
- data->glViewport(0, 0, texture->w, texture->h);
- return 0;
-}
-
SDL_Renderer *
GLES_CreateRenderer(SDL_Window * window, Uint32 flags)
{
@@ -361,6 +295,7 @@
renderer->UpdateTexture = GLES_UpdateTexture;
renderer->LockTexture = GLES_LockTexture;
renderer->UnlockTexture = GLES_UnlockTexture;
+ renderer->SetTargetTexture = GLES_SetTargetTexture;
renderer->UpdateViewport = GLES_UpdateViewport;
renderer->RenderClear = GLES_RenderClear;
renderer->RenderDrawPoints = GLES_RenderDrawPoints;
@@ -372,10 +307,9 @@
renderer->DestroyTexture = GLES_DestroyTexture;
renderer->DestroyRenderer = GLES_DestroyRenderer;
renderer->info = GLES_RenderDriver.info;
- renderer->info.flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE;
+ renderer->info.flags = SDL_RENDERER_ACCELERATED;
renderer->driverdata = data;
renderer->window = window;
- renderer->SetTargetTexture = GLES_SetTargetTexture;
data->context = SDL_GL_CreateContext(window);
if (!data->context) {
@@ -421,9 +355,9 @@
if (SDL_GL_ExtensionSupported("GL_OES_framebuffer_object")) {
data->GL_OES_framebuffer_object_supported = SDL_TRUE;
+ renderer->info.flags |= SDL_RENDERER_TARGETTEXTURE;
}
data->framebuffers = NULL;
- data->renderTarget = NULL;
/* Set up parameters for rendering */
GLES_ResetState(renderer);
@@ -641,6 +575,33 @@
}
static int
+GLES_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+ GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
+ GLES_TextureData *texturedata = NULL;
+ GLenum status;
+
+ GLES_ActivateRenderer(renderer);
+
+ if (texture == NULL) {
+ data->glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
+ return 0;
+ }
+
+ texturedata = (GLES_TextureData *) texture->driverdata;
+ data->glBindFramebufferOES(GL_FRAMEBUFFER_OES, texturedata->fbo->FBO);
+ /* TODO: check if texture pixel format allows this operation */
+ data->glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, texturedata->type, texturedata->texture, 0);
+ /* Check FBO status */
+ status = data->glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
+ if (status != GL_FRAMEBUFFER_COMPLETE_OES) {
+ SDL_SetError("glFramebufferTexture2DOES() failed");
+ return -1;
+ }
+ return 0;
+}
+
+static int
GLES_UpdateViewport(SDL_Renderer * renderer)
{
GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
@@ -870,7 +831,7 @@
SDL_Window *window = renderer->window;
SDL_GetWindowSize(window, &w, &h);
- if (data->renderTarget != NULL) {
+ if (renderer->target) {
cropRect[0] = srcrect->x;
cropRect[1] = srcrect->y;
cropRect[2] = srcrect->w;
--- a/src/render/opengles2/SDL_render_gles2.c Sat Jan 21 22:14:38 2012 -0500
+++ b/src/render/opengles2/SDL_render_gles2.c Sat Jan 21 22:22:30 2012 -0500
@@ -145,8 +145,6 @@
#include "SDL_gles2funcs.h"
#undef SDL_PROC
GLES2_FBOList *framebuffers;
- SDL_Texture *renderTarget;
- SDL_Rect viewport_copy;
int shader_format_count;
GLenum *shader_formats;
@@ -166,8 +164,8 @@
const SDL_WindowEvent *event);
static int GLES2_UpdateViewport(SDL_Renderer * renderer);
static void GLES2_DestroyRenderer(SDL_Renderer *renderer);
+static int GLES2_SetOrthographicProjection(SDL_Renderer *renderer);
-static int GLES2_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture);
static SDL_GLContext SDL_CurrentContext = NULL;
@@ -329,6 +327,7 @@
static void GLES2_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture);
static int GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect,
const void *pixels, int pitch);
+static int GLES2_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture);
static GLenum
GetScaleQuality(void)
@@ -533,6 +532,33 @@
return 0;
}
+static int
+GLES2_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+ GLES2_DriverContext *data = (GLES2_DriverContext *) renderer->driverdata;
+ GLES2_TextureData *texturedata = NULL;
+ GLenum status;
+
+ if (texture == NULL) {
+ data->glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ } else {
+ texturedata = (GLES2_TextureData *) texture->driverdata;
+ data->glBindFramebuffer(GL_FRAMEBUFFER, texturedata->fbo->FBO);
+ /* TODO: check if texture pixel format allows this operation */
+ data->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texturedata->texture_type, texturedata->texture, 0);
+ /* Check FBO status */
+ status = data->glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ if (status != GL_FRAMEBUFFER_COMPLETE) {
+ SDL_SetError("glFramebufferTexture2D() failed");
+ return -1;
+ }
+ }
+ if (data->current_program) {
+ GLES2_SetOrthographicProjection(renderer);
+ }
+ return 0;
+}
+
/*************************************************************************************************
* Shader management functions *
*************************************************************************************************/
@@ -546,7 +572,6 @@
SDL_BlendMode blendMode);
static int GLES2_SelectProgram(SDL_Renderer *renderer, GLES2_ImageSource source,
SDL_BlendMode blendMode);
-static int GLES2_SetOrthographicProjection(SDL_Renderer *renderer);
static GLES2_ProgramCacheEntry *
GLES2_CacheProgram(SDL_Renderer *renderer, GLES2_ShaderCacheEntry *vertex,
@@ -1128,13 +1153,13 @@
/* Activate an appropriate shader and set the projection matrix */
blendMode = texture->blendMode;
- if (rdata->renderTarget!=NULL) {
+ if (renderer->target) {
/* Check if we need to do color mapping between the source and render target textures */
- if (rdata->renderTarget->format != texture->format) {
+ if (renderer->target->format != texture->format) {
switch (texture->format)
{
case SDL_PIXELFORMAT_ABGR8888:
- switch (rdata->renderTarget->format)
+ switch (renderer->target->format)
{
case SDL_PIXELFORMAT_ARGB8888:
case SDL_PIXELFORMAT_RGB888:
@@ -1146,7 +1171,7 @@
}
break;
case SDL_PIXELFORMAT_ARGB8888:
- switch (rdata->renderTarget->format)
+ switch (renderer->target->format)
{
case SDL_PIXELFORMAT_ABGR8888:
case SDL_PIXELFORMAT_BGR888:
@@ -1158,7 +1183,7 @@
}
break;
case SDL_PIXELFORMAT_BGR888:
- switch (rdata->renderTarget->format)
+ switch (renderer->target->format)
{
case SDL_PIXELFORMAT_ABGR8888:
sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR;
@@ -1172,7 +1197,7 @@
}
break;
case SDL_PIXELFORMAT_RGB888:
- switch (rdata->renderTarget->format)
+ switch (renderer->target->format)
{
case SDL_PIXELFORMAT_ABGR8888:
sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
@@ -1230,7 +1255,7 @@
GLES2_SetTexCoords(rdata, SDL_TRUE);
/* Emit the textured quad */
- if (rdata->renderTarget!=NULL) {
+ if (renderer->target) {
// Flip the texture vertically to compensate for the inversion it'll be subjected to later when it's rendered to the screen
vertices[0] = (GLfloat)dstrect->x;
vertices[1] = (GLfloat)renderer->viewport.h-dstrect->y;
@@ -1356,60 +1381,6 @@
rdata->glDisableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD);
}
-static int
-GLES2_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture)
-{
- GLES2_DriverContext *data = (GLES2_DriverContext *) renderer->driverdata;
- GLES2_TextureData *texturedata = NULL;
- GLenum status;
- SDL_BlendMode blendMode;
-
- if (!renderer) return -1;
-
- blendMode = texture->blendMode;
- if (texture == NULL) {
- if (data->renderTarget!=NULL) {
- data->glBindFramebuffer(GL_FRAMEBUFFER, 0);
- renderer->viewport = data->viewport_copy;
- data->renderTarget = NULL;
- data->glViewport(renderer->viewport.x, renderer->viewport.y, renderer->viewport.w, renderer->viewport.h);
- if(data->current_program) GLES2_SetOrthographicProjection(renderer);
- }
- return 0;
- }
- if (renderer != texture->renderer) return -1;
- if (data->renderTarget==NULL) {
- // Keep a copy of the default viewport to restore when texture==NULL
- data->viewport_copy = renderer->viewport;
- }
-
- texturedata = (GLES2_TextureData *) texture->driverdata;
- if (!texturedata) {
- if (texture->native && texture->native->driverdata) {
- texture = texture->native;
- texturedata = texture->driverdata;
- }
- else return -1;
- }
- data->glBindFramebuffer(GL_FRAMEBUFFER, texturedata->fbo->FBO);
- /* TODO: check if texture pixel format allows this operation */
- data->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texturedata->texture_type, texturedata->texture, 0);
- /* Check FBO status */
- status = data->glCheckFramebufferStatus(GL_FRAMEBUFFER);
- if (status != GL_FRAMEBUFFER_COMPLETE) {
- return -1;
- }
-
- renderer->viewport.x = 0;
- renderer->viewport.y = 0;
- renderer->viewport.w = texture->w;
- renderer->viewport.h = texture->h;
- data->renderTarget = texture;
- data->glViewport(0, 0, texture->w, texture->h);
- if(data->current_program) GLES2_SetOrthographicProjection(renderer);
- return 0;
-}
-
static SDL_Renderer *
GLES2_CreateRenderer(SDL_Window *window, Uint32 flags)
{
@@ -1511,7 +1482,6 @@
#endif /* ZUNE_HD */
rdata->framebuffers = NULL;
- rdata->renderTarget = NULL;
/* Populate the function pointers for the module */
renderer->WindowEvent = &GLES2_WindowEvent;
@@ -1519,6 +1489,7 @@
renderer->UpdateTexture = &GLES2_UpdateTexture;
renderer->LockTexture = &GLES2_LockTexture;
renderer->UnlockTexture = &GLES2_UnlockTexture;
+ renderer->SetTargetTexture = &GLES2_SetTargetTexture;
renderer->UpdateViewport = &GLES2_UpdateViewport;
renderer->RenderClear = &GLES2_RenderClear;
renderer->RenderDrawPoints = &GLES2_RenderDrawPoints;
@@ -1529,7 +1500,6 @@
renderer->RenderPresent = &GLES2_RenderPresent;
renderer->DestroyTexture = &GLES2_DestroyTexture;
renderer->DestroyRenderer = &GLES2_DestroyRenderer;
- renderer->SetTargetTexture = &GLES2_SetTargetTexture;
GLES2_ResetState(renderer);
--- a/src/render/software/SDL_render_sw.c Sat Jan 21 22:14:38 2012 -0500
+++ b/src/render/software/SDL_render_sw.c Sat Jan 21 22:22:30 2012 -0500
@@ -51,6 +51,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 int SW_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture);
static int SW_UpdateViewport(SDL_Renderer * renderer);
static int SW_RenderClear(SDL_Renderer * renderer);
static int SW_RenderDrawPoints(SDL_Renderer * renderer,
@@ -72,7 +73,7 @@
SW_CreateRenderer,
{
"software",
- SDL_RENDERER_SOFTWARE,
+ SDL_RENDERER_SOFTWARE | SDL_RENDERER_TARGETTEXTURE,
8,
{
SDL_PIXELFORMAT_RGB555,
@@ -91,6 +92,7 @@
typedef struct
{
SDL_Surface *surface;
+ SDL_Surface *window;
} SW_RenderData;
@@ -100,7 +102,10 @@
SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
if (!data->surface) {
- data->surface = SDL_GetWindowSurface(renderer->window);
+ data->surface = data->window;
+ }
+ if (!data->surface) {
+ data->surface = data->window = SDL_GetWindowSurface(renderer->window);
SW_UpdateViewport(renderer);
}
@@ -140,8 +145,8 @@
renderer->UpdateTexture = SW_UpdateTexture;
renderer->LockTexture = SW_LockTexture;
renderer->UnlockTexture = SW_UnlockTexture;
+ renderer->SetTargetTexture = SW_SetTargetTexture;
renderer->UpdateViewport = SW_UpdateViewport;
- renderer->DestroyTexture = SW_DestroyTexture;
renderer->RenderClear = SW_RenderClear;
renderer->RenderDrawPoints = SW_RenderDrawPoints;
renderer->RenderDrawLines = SW_RenderDrawLines;
@@ -149,6 +154,7 @@
renderer->RenderCopy = SW_RenderCopy;
renderer->RenderReadPixels = SW_RenderReadPixels;
renderer->RenderPresent = SW_RenderPresent;
+ renderer->DestroyTexture = SW_DestroyTexture;
renderer->DestroyRenderer = SW_DestroyRenderer;
renderer->info = SW_RenderDriver.info;
renderer->driverdata = data;
@@ -277,6 +283,19 @@
}
static int
+SW_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+ SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
+
+ if (texture ) {
+ data->surface = (SDL_Surface *) texture->driverdata;
+ } else {
+ data->surface = data->window;
+ }
+ return 0;
+}
+
+static int
SW_UpdateViewport(SDL_Renderer * renderer)
{
SW_RenderData *data = (SW_RenderData *) renderer->driverdata;