Reorganized the render target code, moving the viewport handling to the general code and adding software implementation.

This commit is contained in:
Sam Lantinga 2012-01-21 22:22:30 -05:00
parent fb87e98b8a
commit da686e5bd4
7 changed files with 260 additions and 342 deletions

View file

@ -106,11 +106,16 @@ SDL_RendererEventWatch(void *userdata, SDL_Event *event)
SDL_Rect viewport; SDL_Rect viewport;
SDL_GetWindowSize(window, &w, &h); SDL_GetWindowSize(window, &w, &h);
viewport.x = (w - renderer->viewport.w) / 2; if (renderer->target) {
viewport.y = (h - renderer->viewport.h) / 2; renderer->viewport_backup.x = (w - renderer->viewport_backup.w) / 2;
viewport.w = renderer->viewport.w; renderer->viewport_backup.y = (h - renderer->viewport_backup.h) / 2;
viewport.h = renderer->viewport.h; } else {
SDL_RenderSetViewport(renderer, &viewport); 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) { } else if (event->window.event == SDL_WINDOWEVENT_MINIMIZED) {
renderer->minimized = SDL_TRUE; renderer->minimized = SDL_TRUE;
} else if (event->window.event == SDL_WINDOWEVENT_RESTORED) { } else if (event->window.event == SDL_WINDOWEVENT_RESTORED) {
@ -796,6 +801,72 @@ SDL_UnlockTexture(SDL_Texture * texture)
} }
} }
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 int
SDL_RenderSetViewport(SDL_Renderer * renderer, const SDL_Rect * rect) SDL_RenderSetViewport(SDL_Renderer * renderer, const SDL_Rect * rect)
{ {
@ -1150,35 +1221,6 @@ SDL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
format, pixels, pitch); 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 void
SDL_RenderPresent(SDL_Renderer * renderer) SDL_RenderPresent(SDL_Renderer * renderer)
{ {

View file

@ -77,6 +77,7 @@ struct SDL_Renderer
int (*LockTexture) (SDL_Renderer * renderer, SDL_Texture * texture, int (*LockTexture) (SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * rect, void **pixels, int *pitch); const SDL_Rect * rect, void **pixels, int *pitch);
void (*UnlockTexture) (SDL_Renderer * renderer, SDL_Texture * texture); void (*UnlockTexture) (SDL_Renderer * renderer, SDL_Texture * texture);
int (*SetTargetTexture) (SDL_Renderer * renderer, SDL_Texture * texture);
int (*UpdateViewport) (SDL_Renderer * renderer); int (*UpdateViewport) (SDL_Renderer * renderer);
int (*RenderClear) (SDL_Renderer * renderer); int (*RenderClear) (SDL_Renderer * renderer);
int (*RenderDrawPoints) (SDL_Renderer * renderer, const SDL_Point * points, int (*RenderDrawPoints) (SDL_Renderer * renderer, const SDL_Point * points,
@ -87,7 +88,6 @@ struct SDL_Renderer
int count); int count);
int (*RenderCopy) (SDL_Renderer * renderer, SDL_Texture * texture, int (*RenderCopy) (SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * srcrect, const SDL_Rect * dstrect); 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, int (*RenderReadPixels) (SDL_Renderer * renderer, const SDL_Rect * rect,
Uint32 format, void * pixels, int pitch); Uint32 format, void * pixels, int pitch);
void (*RenderPresent) (SDL_Renderer * renderer); void (*RenderPresent) (SDL_Renderer * renderer);
@ -104,9 +104,11 @@ struct SDL_Renderer
/* The drawable area within the window */ /* The drawable area within the window */
SDL_Rect viewport; SDL_Rect viewport;
SDL_Rect viewport_backup;
/* The list of textures */ /* The list of textures */
SDL_Texture *textures; SDL_Texture *textures;
SDL_Texture *target;
Uint8 r, g, b, a; /**< Color for drawing operations values */ Uint8 r, g, b, a; /**< Color for drawing operations values */
SDL_BlendMode blendMode; /**< The drawing blend mode */ SDL_BlendMode blendMode; /**< The drawing blend mode */

View file

@ -99,6 +99,7 @@ static int D3D_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
static int D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, static int D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * rect, void **pixels, int *pitch); const SDL_Rect * rect, void **pixels, int *pitch);
static void D3D_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture); 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_UpdateViewport(SDL_Renderer * renderer);
static int D3D_RenderClear(SDL_Renderer * renderer); static int D3D_RenderClear(SDL_Renderer * renderer);
static int D3D_RenderDrawPoints(SDL_Renderer * renderer, static int D3D_RenderDrawPoints(SDL_Renderer * renderer,
@ -111,7 +112,6 @@ static int D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * srcrect, const SDL_Rect * dstrect); const SDL_Rect * srcrect, const SDL_Rect * dstrect);
static int D3D_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, static int D3D_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
Uint32 format, void * pixels, int pitch); 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_RenderPresent(SDL_Renderer * renderer);
static void D3D_DestroyTexture(SDL_Renderer * renderer, static void D3D_DestroyTexture(SDL_Renderer * renderer,
SDL_Texture * texture); SDL_Texture * texture);
@ -141,10 +141,6 @@ typedef struct
D3DTEXTUREFILTERTYPE scaleMode; D3DTEXTUREFILTERTYPE scaleMode;
IDirect3DSurface9 *defaultRenderTarget; IDirect3DSurface9 *defaultRenderTarget;
IDirect3DSurface9 *currentRenderTarget; IDirect3DSurface9 *currentRenderTarget;
SDL_bool renderTargetActive;
SDL_Rect viewport_copy;
Uint32 NumSimultaneousRTs;
} D3D_RenderData; } D3D_RenderData;
typedef struct typedef struct
@ -392,6 +388,7 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags)
renderer->UpdateTexture = D3D_UpdateTexture; renderer->UpdateTexture = D3D_UpdateTexture;
renderer->LockTexture = D3D_LockTexture; renderer->LockTexture = D3D_LockTexture;
renderer->UnlockTexture = D3D_UnlockTexture; renderer->UnlockTexture = D3D_UnlockTexture;
renderer->SetTargetTexture = D3D_SetTargetTexture;
renderer->UpdateViewport = D3D_UpdateViewport; renderer->UpdateViewport = D3D_UpdateViewport;
renderer->RenderClear = D3D_RenderClear; renderer->RenderClear = D3D_RenderClear;
renderer->RenderDrawPoints = D3D_RenderDrawPoints; renderer->RenderDrawPoints = D3D_RenderDrawPoints;
@ -399,14 +396,13 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags)
renderer->RenderFillRects = D3D_RenderFillRects; renderer->RenderFillRects = D3D_RenderFillRects;
renderer->RenderCopy = D3D_RenderCopy; renderer->RenderCopy = D3D_RenderCopy;
renderer->RenderReadPixels = D3D_RenderReadPixels; renderer->RenderReadPixels = D3D_RenderReadPixels;
renderer->SetTargetTexture = D3D_SetTargetTexture;
renderer->RenderPresent = D3D_RenderPresent; renderer->RenderPresent = D3D_RenderPresent;
renderer->DestroyTexture = D3D_DestroyTexture; renderer->DestroyTexture = D3D_DestroyTexture;
renderer->DestroyRenderer = D3D_DestroyRenderer; renderer->DestroyRenderer = D3D_DestroyRenderer;
renderer->info = D3D_RenderDriver.info; renderer->info = D3D_RenderDriver.info;
renderer->driverdata = data; renderer->driverdata = data;
renderer->info.flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE; renderer->info.flags = SDL_RENDERER_ACCELERATED;
SDL_VERSION(&windowinfo.version); SDL_VERSION(&windowinfo.version);
SDL_GetWindowWMInfo(window, &windowinfo); SDL_GetWindowWMInfo(window, &windowinfo);
@ -486,7 +482,9 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags)
IDirect3DDevice9_GetDeviceCaps(data->device, &caps); IDirect3DDevice9_GetDeviceCaps(data->device, &caps);
renderer->info.max_texture_width = caps.MaxTextureWidth; renderer->info.max_texture_width = caps.MaxTextureWidth;
renderer->info.max_texture_height = caps.MaxTextureHeight; 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 */ /* Set up parameters for rendering */
IDirect3DDevice9_SetVertexShader(data->device, NULL); IDirect3DDevice9_SetVertexShader(data->device, NULL);
@ -519,7 +517,6 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags)
/* Store the default render target */ /* Store the default render target */
IDirect3DDevice9_GetRenderTarget(data->device, 0, &data->defaultRenderTarget ); IDirect3DDevice9_GetRenderTarget(data->device, 0, &data->defaultRenderTarget );
data->currentRenderTarget = NULL; data->currentRenderTarget = NULL;
data->renderTargetActive = SDL_FALSE;
/* Set an identity world and view matrix */ /* Set an identity world and view matrix */
matrix.m[0][0] = 1.0f; matrix.m[0][0] = 1.0f;
@ -568,79 +565,6 @@ GetScaleQuality(void)
} }
} }
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 static int
D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
{ {
@ -668,11 +592,10 @@ D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
} else } else
#endif #endif
if (texture->access == SDL_TEXTUREACCESS_TARGET) { 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; usage = D3DUSAGE_RENDERTARGET;
} } else {
else
{
pool = D3DPOOL_MANAGED; pool = D3DPOOL_MANAGED;
usage = 0; usage = 0;
} }
@ -810,6 +733,41 @@ D3D_UpdateViewport(SDL_Renderer * renderer)
return 0; return 0;
} }
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 static int
D3D_RenderClear(SDL_Renderer * renderer) D3D_RenderClear(SDL_Renderer * renderer)
{ {

View file

@ -54,6 +54,7 @@ static int GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
static int GL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, static int GL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * rect, void **pixels, int *pitch); const SDL_Rect * rect, void **pixels, int *pitch);
static void GL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture); 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_UpdateViewport(SDL_Renderer * renderer);
static int GL_RenderClear(SDL_Renderer * renderer); static int GL_RenderClear(SDL_Renderer * renderer);
static int GL_RenderDrawPoints(SDL_Renderer * renderer, static int GL_RenderDrawPoints(SDL_Renderer * renderer,
@ -66,7 +67,6 @@ static int GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * srcrect, const SDL_Rect * dstrect); const SDL_Rect * srcrect, const SDL_Rect * dstrect);
static int GL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, static int GL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
Uint32 pixel_format, void * pixels, int pitch); 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_RenderPresent(SDL_Renderer * renderer);
static void GL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture); static void GL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture);
static void GL_DestroyRenderer(SDL_Renderer * renderer); static void GL_DestroyRenderer(SDL_Renderer * renderer);
@ -104,8 +104,6 @@ typedef struct
SDL_bool GL_EXT_framebuffer_object_supported; SDL_bool GL_EXT_framebuffer_object_supported;
GL_FBOList *framebuffers; GL_FBOList *framebuffers;
SDL_Texture *renderTarget;
SDL_Rect viewport_copy;
/* OpenGL functions */ /* OpenGL functions */
#define SDL_PROC(ret,func,params) ret (APIENTRY *func) params; #define SDL_PROC(ret,func,params) ret (APIENTRY *func) params;
@ -309,19 +307,19 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags)
renderer->UpdateTexture = GL_UpdateTexture; renderer->UpdateTexture = GL_UpdateTexture;
renderer->LockTexture = GL_LockTexture; renderer->LockTexture = GL_LockTexture;
renderer->UnlockTexture = GL_UnlockTexture; renderer->UnlockTexture = GL_UnlockTexture;
renderer->SetTargetTexture = GL_SetTargetTexture;
renderer->UpdateViewport = GL_UpdateViewport; renderer->UpdateViewport = GL_UpdateViewport;
renderer->RenderClear = GL_RenderClear; renderer->RenderClear = GL_RenderClear;
renderer->RenderDrawPoints = GL_RenderDrawPoints; renderer->RenderDrawPoints = GL_RenderDrawPoints;
renderer->RenderDrawLines = GL_RenderDrawLines; renderer->RenderDrawLines = GL_RenderDrawLines;
renderer->RenderFillRects = GL_RenderFillRects; renderer->RenderFillRects = GL_RenderFillRects;
renderer->RenderCopy = GL_RenderCopy; renderer->RenderCopy = GL_RenderCopy;
renderer->SetTargetTexture = GL_SetTargetTexture;
renderer->RenderReadPixels = GL_RenderReadPixels; renderer->RenderReadPixels = GL_RenderReadPixels;
renderer->RenderPresent = GL_RenderPresent; renderer->RenderPresent = GL_RenderPresent;
renderer->DestroyTexture = GL_DestroyTexture; renderer->DestroyTexture = GL_DestroyTexture;
renderer->DestroyRenderer = GL_DestroyRenderer; renderer->DestroyRenderer = GL_DestroyRenderer;
renderer->info = GL_RenderDriver.info; renderer->info = GL_RenderDriver.info;
renderer->info.flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE; renderer->info.flags = SDL_RENDERER_ACCELERATED;
renderer->driverdata = data; renderer->driverdata = data;
renderer->window = window; renderer->window = window;
@ -399,11 +397,11 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags)
SDL_GL_GetProcAddress("glFramebufferTexture2DEXT"); SDL_GL_GetProcAddress("glFramebufferTexture2DEXT");
data->glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC) data->glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC)
SDL_GL_GetProcAddress("glBindFramebufferEXT"); SDL_GL_GetProcAddress("glBindFramebufferEXT");
data->glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) data->glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)
SDL_GL_GetProcAddress("glCheckFramebufferStatusEXT"); SDL_GL_GetProcAddress("glCheckFramebufferStatusEXT");
renderer->info.flags |= SDL_RENDERER_TARGETTEXTURE;
} }
data->framebuffers = NULL; data->framebuffers = NULL;
data->renderTarget = NULL;
/* Set up parameters for rendering */ /* Set up parameters for rendering */
GL_ResetState(renderer); GL_ResetState(renderer);
@ -465,74 +463,6 @@ GetScaleQuality(void)
} }
} }
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 static int
GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
{ {
@ -776,6 +706,33 @@ GL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
GL_UpdateTexture(renderer, texture, rect, pixels, data->pitch); GL_UpdateTexture(renderer, texture, rect, pixels, data->pitch);
} }
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 static int
GL_UpdateViewport(SDL_Renderer * renderer) GL_UpdateViewport(SDL_Renderer * renderer)
{ {
@ -791,10 +748,19 @@ GL_UpdateViewport(SDL_Renderer * renderer)
data->glMatrixMode(GL_PROJECTION); data->glMatrixMode(GL_PROJECTION);
data->glLoadIdentity(); data->glLoadIdentity();
data->glOrtho((GLdouble) 0, if (renderer->target) {
(GLdouble) renderer->viewport.w, data->glOrtho((GLdouble) 0,
(GLdouble) renderer->viewport.h, (GLdouble) renderer->viewport.w,
(GLdouble) 0, 0.0, 1.0); (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; return 0;
} }

View file

@ -56,6 +56,8 @@ static int GLES_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * rect, void **pixels, int *pitch); const SDL_Rect * rect, void **pixels, int *pitch);
static void GLES_UnlockTexture(SDL_Renderer * renderer, static void GLES_UnlockTexture(SDL_Renderer * renderer,
SDL_Texture * texture); SDL_Texture * texture);
static int GLES_SetTargetTexture(SDL_Renderer * renderer,
SDL_Texture * texture);
static int GLES_UpdateViewport(SDL_Renderer * renderer); static int GLES_UpdateViewport(SDL_Renderer * renderer);
static int GLES_RenderClear(SDL_Renderer * renderer); static int GLES_RenderClear(SDL_Renderer * renderer);
static int GLES_RenderDrawPoints(SDL_Renderer * renderer, static int GLES_RenderDrawPoints(SDL_Renderer * renderer,
@ -73,7 +75,6 @@ static void GLES_RenderPresent(SDL_Renderer * renderer);
static void GLES_DestroyTexture(SDL_Renderer * renderer, static void GLES_DestroyTexture(SDL_Renderer * renderer,
SDL_Texture * texture); SDL_Texture * texture);
static void GLES_DestroyRenderer(SDL_Renderer * renderer); static void GLES_DestroyRenderer(SDL_Renderer * renderer);
static int GLES_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture);
typedef struct GLES_FBOList GLES_FBOList; typedef struct GLES_FBOList GLES_FBOList;
@ -110,8 +111,6 @@ typedef struct
#undef SDL_PROC #undef SDL_PROC
SDL_bool GL_OES_framebuffer_object_supported; SDL_bool GL_OES_framebuffer_object_supported;
GLES_FBOList *framebuffers; GLES_FBOList *framebuffers;
SDL_Texture *renderTarget;
SDL_Rect viewport_copy;
SDL_bool useDrawTexture; SDL_bool useDrawTexture;
SDL_bool GL_OES_draw_texture_supported; SDL_bool GL_OES_draw_texture_supported;
@ -257,71 +256,6 @@ GLES_ResetState(SDL_Renderer *renderer)
data->glDisableClientState(GL_TEXTURE_COORD_ARRAY); 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 * SDL_Renderer *
GLES_CreateRenderer(SDL_Window * window, Uint32 flags) GLES_CreateRenderer(SDL_Window * window, Uint32 flags)
{ {
@ -361,6 +295,7 @@ GLES_CreateRenderer(SDL_Window * window, Uint32 flags)
renderer->UpdateTexture = GLES_UpdateTexture; renderer->UpdateTexture = GLES_UpdateTexture;
renderer->LockTexture = GLES_LockTexture; renderer->LockTexture = GLES_LockTexture;
renderer->UnlockTexture = GLES_UnlockTexture; renderer->UnlockTexture = GLES_UnlockTexture;
renderer->SetTargetTexture = GLES_SetTargetTexture;
renderer->UpdateViewport = GLES_UpdateViewport; renderer->UpdateViewport = GLES_UpdateViewport;
renderer->RenderClear = GLES_RenderClear; renderer->RenderClear = GLES_RenderClear;
renderer->RenderDrawPoints = GLES_RenderDrawPoints; renderer->RenderDrawPoints = GLES_RenderDrawPoints;
@ -372,10 +307,9 @@ GLES_CreateRenderer(SDL_Window * window, Uint32 flags)
renderer->DestroyTexture = GLES_DestroyTexture; renderer->DestroyTexture = GLES_DestroyTexture;
renderer->DestroyRenderer = GLES_DestroyRenderer; renderer->DestroyRenderer = GLES_DestroyRenderer;
renderer->info = GLES_RenderDriver.info; renderer->info = GLES_RenderDriver.info;
renderer->info.flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE; renderer->info.flags = SDL_RENDERER_ACCELERATED;
renderer->driverdata = data; renderer->driverdata = data;
renderer->window = window; renderer->window = window;
renderer->SetTargetTexture = GLES_SetTargetTexture;
data->context = SDL_GL_CreateContext(window); data->context = SDL_GL_CreateContext(window);
if (!data->context) { if (!data->context) {
@ -421,9 +355,9 @@ GLES_CreateRenderer(SDL_Window * window, Uint32 flags)
if (SDL_GL_ExtensionSupported("GL_OES_framebuffer_object")) { if (SDL_GL_ExtensionSupported("GL_OES_framebuffer_object")) {
data->GL_OES_framebuffer_object_supported = SDL_TRUE; data->GL_OES_framebuffer_object_supported = SDL_TRUE;
renderer->info.flags |= SDL_RENDERER_TARGETTEXTURE;
} }
data->framebuffers = NULL; data->framebuffers = NULL;
data->renderTarget = NULL;
/* Set up parameters for rendering */ /* Set up parameters for rendering */
GLES_ResetState(renderer); GLES_ResetState(renderer);
@ -640,6 +574,33 @@ GLES_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
GLES_UpdateTexture(renderer, texture, &rect, data->pixels, data->pitch); GLES_UpdateTexture(renderer, texture, &rect, data->pixels, data->pitch);
} }
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 static int
GLES_UpdateViewport(SDL_Renderer * renderer) GLES_UpdateViewport(SDL_Renderer * renderer)
{ {
@ -870,7 +831,7 @@ GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
SDL_Window *window = renderer->window; SDL_Window *window = renderer->window;
SDL_GetWindowSize(window, &w, &h); SDL_GetWindowSize(window, &w, &h);
if (data->renderTarget != NULL) { if (renderer->target) {
cropRect[0] = srcrect->x; cropRect[0] = srcrect->x;
cropRect[1] = srcrect->y; cropRect[1] = srcrect->y;
cropRect[2] = srcrect->w; cropRect[2] = srcrect->w;

View file

@ -145,8 +145,6 @@ typedef struct GLES2_DriverContext
#include "SDL_gles2funcs.h" #include "SDL_gles2funcs.h"
#undef SDL_PROC #undef SDL_PROC
GLES2_FBOList *framebuffers; GLES2_FBOList *framebuffers;
SDL_Texture *renderTarget;
SDL_Rect viewport_copy;
int shader_format_count; int shader_format_count;
GLenum *shader_formats; GLenum *shader_formats;
@ -166,8 +164,8 @@ static void GLES2_WindowEvent(SDL_Renderer * renderer,
const SDL_WindowEvent *event); const SDL_WindowEvent *event);
static int GLES2_UpdateViewport(SDL_Renderer * renderer); static int GLES2_UpdateViewport(SDL_Renderer * renderer);
static void GLES2_DestroyRenderer(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; static SDL_GLContext SDL_CurrentContext = NULL;
@ -329,6 +327,7 @@ static int GLES2_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture, const
static void GLES2_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture); static void GLES2_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture);
static int GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, static int GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect,
const void *pixels, int pitch); const void *pixels, int pitch);
static int GLES2_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture);
static GLenum static GLenum
GetScaleQuality(void) GetScaleQuality(void)
@ -533,6 +532,33 @@ GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect
return 0; 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 * * Shader management functions *
*************************************************************************************************/ *************************************************************************************************/
@ -546,7 +572,6 @@ static GLES2_ProgramCacheEntry *GLES2_CacheProgram(SDL_Renderer *renderer,
SDL_BlendMode blendMode); SDL_BlendMode blendMode);
static int GLES2_SelectProgram(SDL_Renderer *renderer, GLES2_ImageSource source, static int GLES2_SelectProgram(SDL_Renderer *renderer, GLES2_ImageSource source,
SDL_BlendMode blendMode); SDL_BlendMode blendMode);
static int GLES2_SetOrthographicProjection(SDL_Renderer *renderer);
static GLES2_ProgramCacheEntry * static GLES2_ProgramCacheEntry *
GLES2_CacheProgram(SDL_Renderer *renderer, GLES2_ShaderCacheEntry *vertex, GLES2_CacheProgram(SDL_Renderer *renderer, GLES2_ShaderCacheEntry *vertex,
@ -1128,13 +1153,13 @@ GLES2_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *s
/* Activate an appropriate shader and set the projection matrix */ /* Activate an appropriate shader and set the projection matrix */
blendMode = texture->blendMode; 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 */ /* 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) switch (texture->format)
{ {
case SDL_PIXELFORMAT_ABGR8888: case SDL_PIXELFORMAT_ABGR8888:
switch (rdata->renderTarget->format) switch (renderer->target->format)
{ {
case SDL_PIXELFORMAT_ARGB8888: case SDL_PIXELFORMAT_ARGB8888:
case SDL_PIXELFORMAT_RGB888: case SDL_PIXELFORMAT_RGB888:
@ -1146,7 +1171,7 @@ GLES2_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *s
} }
break; break;
case SDL_PIXELFORMAT_ARGB8888: case SDL_PIXELFORMAT_ARGB8888:
switch (rdata->renderTarget->format) switch (renderer->target->format)
{ {
case SDL_PIXELFORMAT_ABGR8888: case SDL_PIXELFORMAT_ABGR8888:
case SDL_PIXELFORMAT_BGR888: case SDL_PIXELFORMAT_BGR888:
@ -1158,7 +1183,7 @@ GLES2_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *s
} }
break; break;
case SDL_PIXELFORMAT_BGR888: case SDL_PIXELFORMAT_BGR888:
switch (rdata->renderTarget->format) switch (renderer->target->format)
{ {
case SDL_PIXELFORMAT_ABGR8888: case SDL_PIXELFORMAT_ABGR8888:
sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR; sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR;
@ -1172,7 +1197,7 @@ GLES2_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *s
} }
break; break;
case SDL_PIXELFORMAT_RGB888: case SDL_PIXELFORMAT_RGB888:
switch (rdata->renderTarget->format) switch (renderer->target->format)
{ {
case SDL_PIXELFORMAT_ABGR8888: case SDL_PIXELFORMAT_ABGR8888:
sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB; sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
@ -1230,7 +1255,7 @@ GLES2_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *s
GLES2_SetTexCoords(rdata, SDL_TRUE); GLES2_SetTexCoords(rdata, SDL_TRUE);
/* Emit the textured quad */ /* 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 // 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[0] = (GLfloat)dstrect->x;
vertices[1] = (GLfloat)renderer->viewport.h-dstrect->y; vertices[1] = (GLfloat)renderer->viewport.h-dstrect->y;
@ -1356,60 +1381,6 @@ GLES2_ResetState(SDL_Renderer *renderer)
rdata->glDisableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD); 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 * static SDL_Renderer *
GLES2_CreateRenderer(SDL_Window *window, Uint32 flags) GLES2_CreateRenderer(SDL_Window *window, Uint32 flags)
{ {
@ -1511,7 +1482,6 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags)
#endif /* ZUNE_HD */ #endif /* ZUNE_HD */
rdata->framebuffers = NULL; rdata->framebuffers = NULL;
rdata->renderTarget = NULL;
/* Populate the function pointers for the module */ /* Populate the function pointers for the module */
renderer->WindowEvent = &GLES2_WindowEvent; renderer->WindowEvent = &GLES2_WindowEvent;
@ -1519,6 +1489,7 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags)
renderer->UpdateTexture = &GLES2_UpdateTexture; renderer->UpdateTexture = &GLES2_UpdateTexture;
renderer->LockTexture = &GLES2_LockTexture; renderer->LockTexture = &GLES2_LockTexture;
renderer->UnlockTexture = &GLES2_UnlockTexture; renderer->UnlockTexture = &GLES2_UnlockTexture;
renderer->SetTargetTexture = &GLES2_SetTargetTexture;
renderer->UpdateViewport = &GLES2_UpdateViewport; renderer->UpdateViewport = &GLES2_UpdateViewport;
renderer->RenderClear = &GLES2_RenderClear; renderer->RenderClear = &GLES2_RenderClear;
renderer->RenderDrawPoints = &GLES2_RenderDrawPoints; renderer->RenderDrawPoints = &GLES2_RenderDrawPoints;
@ -1529,7 +1500,6 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags)
renderer->RenderPresent = &GLES2_RenderPresent; renderer->RenderPresent = &GLES2_RenderPresent;
renderer->DestroyTexture = &GLES2_DestroyTexture; renderer->DestroyTexture = &GLES2_DestroyTexture;
renderer->DestroyRenderer = &GLES2_DestroyRenderer; renderer->DestroyRenderer = &GLES2_DestroyRenderer;
renderer->SetTargetTexture = &GLES2_SetTargetTexture;
GLES2_ResetState(renderer); GLES2_ResetState(renderer);

View file

@ -51,6 +51,7 @@ static int SW_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
static int SW_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, static int SW_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * rect, void **pixels, int *pitch); const SDL_Rect * rect, void **pixels, int *pitch);
static void SW_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture); 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_UpdateViewport(SDL_Renderer * renderer);
static int SW_RenderClear(SDL_Renderer * renderer); static int SW_RenderClear(SDL_Renderer * renderer);
static int SW_RenderDrawPoints(SDL_Renderer * renderer, static int SW_RenderDrawPoints(SDL_Renderer * renderer,
@ -72,7 +73,7 @@ SDL_RenderDriver SW_RenderDriver = {
SW_CreateRenderer, SW_CreateRenderer,
{ {
"software", "software",
SDL_RENDERER_SOFTWARE, SDL_RENDERER_SOFTWARE | SDL_RENDERER_TARGETTEXTURE,
8, 8,
{ {
SDL_PIXELFORMAT_RGB555, SDL_PIXELFORMAT_RGB555,
@ -91,6 +92,7 @@ SDL_RenderDriver SW_RenderDriver = {
typedef struct typedef struct
{ {
SDL_Surface *surface; SDL_Surface *surface;
SDL_Surface *window;
} SW_RenderData; } SW_RenderData;
@ -100,7 +102,10 @@ SW_ActivateRenderer(SDL_Renderer * renderer)
SW_RenderData *data = (SW_RenderData *) renderer->driverdata; SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
if (!data->surface) { 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); SW_UpdateViewport(renderer);
} }
@ -140,8 +145,8 @@ SW_CreateRendererForSurface(SDL_Surface * surface)
renderer->UpdateTexture = SW_UpdateTexture; renderer->UpdateTexture = SW_UpdateTexture;
renderer->LockTexture = SW_LockTexture; renderer->LockTexture = SW_LockTexture;
renderer->UnlockTexture = SW_UnlockTexture; renderer->UnlockTexture = SW_UnlockTexture;
renderer->SetTargetTexture = SW_SetTargetTexture;
renderer->UpdateViewport = SW_UpdateViewport; renderer->UpdateViewport = SW_UpdateViewport;
renderer->DestroyTexture = SW_DestroyTexture;
renderer->RenderClear = SW_RenderClear; renderer->RenderClear = SW_RenderClear;
renderer->RenderDrawPoints = SW_RenderDrawPoints; renderer->RenderDrawPoints = SW_RenderDrawPoints;
renderer->RenderDrawLines = SW_RenderDrawLines; renderer->RenderDrawLines = SW_RenderDrawLines;
@ -149,6 +154,7 @@ SW_CreateRendererForSurface(SDL_Surface * surface)
renderer->RenderCopy = SW_RenderCopy; renderer->RenderCopy = SW_RenderCopy;
renderer->RenderReadPixels = SW_RenderReadPixels; renderer->RenderReadPixels = SW_RenderReadPixels;
renderer->RenderPresent = SW_RenderPresent; renderer->RenderPresent = SW_RenderPresent;
renderer->DestroyTexture = SW_DestroyTexture;
renderer->DestroyRenderer = SW_DestroyRenderer; renderer->DestroyRenderer = SW_DestroyRenderer;
renderer->info = SW_RenderDriver.info; renderer->info = SW_RenderDriver.info;
renderer->driverdata = data; renderer->driverdata = data;
@ -276,6 +282,19 @@ SW_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
{ {
} }
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 static int
SW_UpdateViewport(SDL_Renderer * renderer) SW_UpdateViewport(SDL_Renderer * renderer)
{ {