Reorganized the render target code, moving the viewport handling to the general code and adding software implementation.
authorSam Lantinga <slouken@libsdl.org>
Sat, 21 Jan 2012 22:22:30 -0500
changeset 6246c70ec935a4bb
parent 6245 9d15de67bff9
child 6247 b6212690f78d
Reorganized the render target code, moving the viewport handling to the general code and adding software implementation.
src/render/SDL_render.c
src/render/SDL_sysrender.h
src/render/direct3d/SDL_render_d3d.c
src/render/opengl/SDL_render_gl.c
src/render/opengles/SDL_render_gles.c
src/render/opengles2/SDL_render_gles2.c
src/render/software/SDL_render_sw.c
     1.1 --- a/src/render/SDL_render.c	Sat Jan 21 22:14:38 2012 -0500
     1.2 +++ b/src/render/SDL_render.c	Sat Jan 21 22:22:30 2012 -0500
     1.3 @@ -106,11 +106,16 @@
     1.4                  SDL_Rect viewport;
     1.5  
     1.6                  SDL_GetWindowSize(window, &w, &h);
     1.7 -                viewport.x = (w - renderer->viewport.w) / 2;
     1.8 -                viewport.y = (h - renderer->viewport.h) / 2;
     1.9 -                viewport.w = renderer->viewport.w;
    1.10 -                viewport.h = renderer->viewport.h;
    1.11 -                SDL_RenderSetViewport(renderer, &viewport);
    1.12 +                if (renderer->target) {
    1.13 +                    renderer->viewport_backup.x = (w - renderer->viewport_backup.w) / 2;
    1.14 +                    renderer->viewport_backup.y = (h - renderer->viewport_backup.h) / 2;
    1.15 +                } else {
    1.16 +                    viewport.x = (w - renderer->viewport.w) / 2;
    1.17 +                    viewport.y = (h - renderer->viewport.h) / 2;
    1.18 +                    viewport.w = renderer->viewport.w;
    1.19 +                    viewport.h = renderer->viewport.h;
    1.20 +                    SDL_RenderSetViewport(renderer, &viewport);
    1.21 +                }
    1.22              } else if (event->window.event == SDL_WINDOWEVENT_MINIMIZED) {
    1.23                  renderer->minimized = SDL_TRUE;
    1.24              } else if (event->window.event == SDL_WINDOWEVENT_RESTORED) {
    1.25 @@ -796,6 +801,72 @@
    1.26      }
    1.27  }
    1.28  
    1.29 +SDL_bool
    1.30 +SDL_RenderTargetSupported(SDL_Renderer *renderer)
    1.31 +{
    1.32 +    if (!renderer || !renderer->SetTargetTexture) {
    1.33 +        return SDL_FALSE;
    1.34 +    }
    1.35 +    return (renderer->info.flags & SDL_RENDERER_TARGETTEXTURE) != 0;
    1.36 +}
    1.37 +
    1.38 +int
    1.39 +SDL_SetTargetTexture(SDL_Renderer *renderer, SDL_Texture *texture)
    1.40 +{
    1.41 +    SDL_Rect viewport;
    1.42 +
    1.43 +    if (!SDL_RenderTargetSupported(renderer)) {
    1.44 +        SDL_Unsupported();
    1.45 +        return -1;
    1.46 +    }
    1.47 +    if (texture == renderer->target) {
    1.48 +        /* Nothing to do! */
    1.49 +        return 0;
    1.50 +    }
    1.51 +
    1.52 +    /* texture == NULL is valid and means reset the target to the window */
    1.53 +    if (texture) {
    1.54 +        CHECK_TEXTURE_MAGIC(texture, -1);
    1.55 +        if (renderer != texture->renderer) {
    1.56 +            SDL_SetError("Texture was not created with this renderer");
    1.57 +            return -1;
    1.58 +        }
    1.59 +        if (!(texture->access & SDL_TEXTUREACCESS_TARGET)) {
    1.60 +            SDL_SetError("Texture not created with SDL_TEXTUREACCESS_TARGET");
    1.61 +            return -1;
    1.62 +        }
    1.63 +        if (texture->native) {
    1.64 +            /* Always render to the native texture */
    1.65 +            texture = texture->native;
    1.66 +        }
    1.67 +    }
    1.68 +
    1.69 +    if (texture && !renderer->target) {
    1.70 +        /* Make a backup of the viewport */
    1.71 +        renderer->viewport_backup = renderer->viewport;
    1.72 +    }
    1.73 +    renderer->target = texture;
    1.74 +
    1.75 +    if (renderer->SetTargetTexture(renderer, texture) < 0) {
    1.76 +        return -1;
    1.77 +    }
    1.78 +
    1.79 +    if (texture) {
    1.80 +        viewport.x = 0;
    1.81 +        viewport.y = 0;
    1.82 +        viewport.w = texture->w;
    1.83 +        viewport.h = texture->h;
    1.84 +    } else {
    1.85 +        viewport = renderer->viewport_backup;
    1.86 +    }
    1.87 +    if (SDL_RenderSetViewport(renderer, &viewport) < 0) {
    1.88 +        return -1;
    1.89 +    }
    1.90 +
    1.91 +    /* All set! */
    1.92 +    return 0;
    1.93 +}
    1.94 +
    1.95  int
    1.96  SDL_RenderSetViewport(SDL_Renderer * renderer, const SDL_Rect * rect)
    1.97  {
    1.98 @@ -1150,35 +1221,6 @@
    1.99                                        format, pixels, pitch);
   1.100  }
   1.101  
   1.102 -SDL_bool
   1.103 -SDL_RenderTargetSupported(SDL_Renderer *renderer)
   1.104 -{
   1.105 -    if (!renderer || !renderer->SetTargetTexture) {
   1.106 -        return SDL_FALSE;
   1.107 -    }
   1.108 -    return (renderer->info.flags & SDL_RENDERER_TARGETTEXTURE) != 0;
   1.109 -}
   1.110 -
   1.111 -int
   1.112 -SDL_SetTargetTexture(SDL_Renderer *renderer, SDL_Texture *texture)
   1.113 -{
   1.114 -    
   1.115 -    if(!renderer) {
   1.116 -        return -1;
   1.117 -    }
   1.118 -    if (!renderer->SetTargetTexture) {
   1.119 -        SDL_Unsupported();
   1.120 -        return -1;
   1.121 -    }
   1.122 -    // Warning: texture==NULL is a valid parameter
   1.123 -    if( texture ) {
   1.124 -        CHECK_TEXTURE_MAGIC(texture, -1);
   1.125 -        if(renderer != texture->renderer) return -1;
   1.126 -    }
   1.127 -    
   1.128 -    return renderer->SetTargetTexture(renderer, texture);
   1.129 -}
   1.130 -
   1.131  void
   1.132  SDL_RenderPresent(SDL_Renderer * renderer)
   1.133  {
     2.1 --- a/src/render/SDL_sysrender.h	Sat Jan 21 22:14:38 2012 -0500
     2.2 +++ b/src/render/SDL_sysrender.h	Sat Jan 21 22:22:30 2012 -0500
     2.3 @@ -77,6 +77,7 @@
     2.4      int (*LockTexture) (SDL_Renderer * renderer, SDL_Texture * texture,
     2.5                          const SDL_Rect * rect, void **pixels, int *pitch);
     2.6      void (*UnlockTexture) (SDL_Renderer * renderer, SDL_Texture * texture);
     2.7 +    int (*SetTargetTexture) (SDL_Renderer * renderer, SDL_Texture * texture);
     2.8      int (*UpdateViewport) (SDL_Renderer * renderer);
     2.9      int (*RenderClear) (SDL_Renderer * renderer);
    2.10      int (*RenderDrawPoints) (SDL_Renderer * renderer, const SDL_Point * points,
    2.11 @@ -87,7 +88,6 @@
    2.12                              int count);
    2.13      int (*RenderCopy) (SDL_Renderer * renderer, SDL_Texture * texture,
    2.14                         const SDL_Rect * srcrect, const SDL_Rect * dstrect);
    2.15 -    int (*SetTargetTexture) (SDL_Renderer * renderer, SDL_Texture * texture);
    2.16      int (*RenderReadPixels) (SDL_Renderer * renderer, const SDL_Rect * rect,
    2.17                               Uint32 format, void * pixels, int pitch);
    2.18      void (*RenderPresent) (SDL_Renderer * renderer);
    2.19 @@ -104,9 +104,11 @@
    2.20  
    2.21      /* The drawable area within the window */
    2.22      SDL_Rect viewport;
    2.23 +    SDL_Rect viewport_backup;
    2.24  
    2.25      /* The list of textures */
    2.26      SDL_Texture *textures;
    2.27 +    SDL_Texture *target;
    2.28  
    2.29      Uint8 r, g, b, a;                   /**< Color for drawing operations values */
    2.30      SDL_BlendMode blendMode;            /**< The drawing blend mode */
     3.1 --- a/src/render/direct3d/SDL_render_d3d.c	Sat Jan 21 22:14:38 2012 -0500
     3.2 +++ b/src/render/direct3d/SDL_render_d3d.c	Sat Jan 21 22:22:30 2012 -0500
     3.3 @@ -99,6 +99,7 @@
     3.4  static int D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
     3.5                             const SDL_Rect * rect, void **pixels, int *pitch);
     3.6  static void D3D_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
     3.7 +static int D3D_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture);
     3.8  static int D3D_UpdateViewport(SDL_Renderer * renderer);
     3.9  static int D3D_RenderClear(SDL_Renderer * renderer);
    3.10  static int D3D_RenderDrawPoints(SDL_Renderer * renderer,
    3.11 @@ -111,7 +112,6 @@
    3.12                            const SDL_Rect * srcrect, const SDL_Rect * dstrect);
    3.13  static int D3D_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
    3.14                                  Uint32 format, void * pixels, int pitch);
    3.15 -static int D3D_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture);
    3.16  static void D3D_RenderPresent(SDL_Renderer * renderer);
    3.17  static void D3D_DestroyTexture(SDL_Renderer * renderer,
    3.18                                 SDL_Texture * texture);
    3.19 @@ -141,10 +141,6 @@
    3.20      D3DTEXTUREFILTERTYPE scaleMode;
    3.21      IDirect3DSurface9 *defaultRenderTarget;
    3.22      IDirect3DSurface9 *currentRenderTarget;
    3.23 -    SDL_bool renderTargetActive;
    3.24 -    SDL_Rect viewport_copy;
    3.25 -    
    3.26 -    Uint32 NumSimultaneousRTs;
    3.27  } D3D_RenderData;
    3.28  
    3.29  typedef struct
    3.30 @@ -392,6 +388,7 @@
    3.31      renderer->UpdateTexture = D3D_UpdateTexture;
    3.32      renderer->LockTexture = D3D_LockTexture;
    3.33      renderer->UnlockTexture = D3D_UnlockTexture;
    3.34 +    renderer->SetTargetTexture = D3D_SetTargetTexture;
    3.35      renderer->UpdateViewport = D3D_UpdateViewport;
    3.36      renderer->RenderClear = D3D_RenderClear;
    3.37      renderer->RenderDrawPoints = D3D_RenderDrawPoints;
    3.38 @@ -399,14 +396,13 @@
    3.39      renderer->RenderFillRects = D3D_RenderFillRects;
    3.40      renderer->RenderCopy = D3D_RenderCopy;
    3.41      renderer->RenderReadPixels = D3D_RenderReadPixels;
    3.42 -    renderer->SetTargetTexture = D3D_SetTargetTexture;
    3.43      renderer->RenderPresent = D3D_RenderPresent;
    3.44      renderer->DestroyTexture = D3D_DestroyTexture;
    3.45      renderer->DestroyRenderer = D3D_DestroyRenderer;
    3.46      renderer->info = D3D_RenderDriver.info;
    3.47      renderer->driverdata = data;
    3.48  
    3.49 -    renderer->info.flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE;
    3.50 +    renderer->info.flags = SDL_RENDERER_ACCELERATED;
    3.51  
    3.52      SDL_VERSION(&windowinfo.version);
    3.53      SDL_GetWindowWMInfo(window, &windowinfo);
    3.54 @@ -486,7 +482,9 @@
    3.55      IDirect3DDevice9_GetDeviceCaps(data->device, &caps);
    3.56      renderer->info.max_texture_width = caps.MaxTextureWidth;
    3.57      renderer->info.max_texture_height = caps.MaxTextureHeight;
    3.58 -    data->NumSimultaneousRTs = caps.NumSimultaneousRTs;
    3.59 +    if (caps.NumSimultaneousRTs >= 2) {
    3.60 +        renderer->info.flags |= SDL_RENDERER_TARGETTEXTURE;
    3.61 +    }
    3.62  
    3.63      /* Set up parameters for rendering */
    3.64      IDirect3DDevice9_SetVertexShader(data->device, NULL);
    3.65 @@ -519,7 +517,6 @@
    3.66      /* Store the default render target */
    3.67      IDirect3DDevice9_GetRenderTarget(data->device, 0, &data->defaultRenderTarget );
    3.68      data->currentRenderTarget = NULL;
    3.69 -    data->renderTargetActive = SDL_FALSE;
    3.70  
    3.71      /* Set an identity world and view matrix */
    3.72      matrix.m[0][0] = 1.0f;
    3.73 @@ -569,79 +566,6 @@
    3.74  }
    3.75  
    3.76  static int
    3.77 -D3D_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture)
    3.78 -{
    3.79 -    D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
    3.80 -    D3D_TextureData *texturedata;
    3.81 -    D3DMATRIX matrix;
    3.82 -    HRESULT result;
    3.83 -
    3.84 -    D3D_ActivateRenderer(renderer);
    3.85 -
    3.86 -    if (data->NumSimultaneousRTs < 2) {
    3.87 -        SDL_Unsupported();
    3.88 -        return -1;
    3.89 -    }
    3.90 -
    3.91 -    // Release the previous render target if it wasn't the default one
    3.92 -    if (data->currentRenderTarget != NULL) {
    3.93 -        IDirect3DSurface9_Release(data->currentRenderTarget);
    3.94 -        data->currentRenderTarget = NULL;
    3.95 -    }
    3.96 -
    3.97 -    /* Prepare an identity world and view matrix */
    3.98 -    matrix.m[0][0] = 1.0f;
    3.99 -    matrix.m[0][1] = 0.0f;
   3.100 -    matrix.m[0][2] = 0.0f;
   3.101 -    matrix.m[0][3] = 0.0f;
   3.102 -    matrix.m[1][0] = 0.0f;
   3.103 -    matrix.m[1][1] = 1.0f;
   3.104 -    matrix.m[1][2] = 0.0f;
   3.105 -    matrix.m[1][3] = 0.0f;
   3.106 -    matrix.m[2][0] = 0.0f;
   3.107 -    matrix.m[2][1] = 0.0f;
   3.108 -    matrix.m[2][2] = 1.0f;
   3.109 -    matrix.m[2][3] = 0.0f;
   3.110 -    matrix.m[3][0] = 0.0f;
   3.111 -    matrix.m[3][1] = 0.0f;
   3.112 -    matrix.m[3][2] = 0.0f;
   3.113 -    matrix.m[3][3] = 1.0f;
   3.114 -
   3.115 -    if (texture == NULL) {
   3.116 -        if (data->renderTargetActive) {
   3.117 -            data->renderTargetActive = SDL_FALSE;
   3.118 -            IDirect3DDevice9_SetRenderTarget(data->device, 0, data->defaultRenderTarget );
   3.119 -            renderer->viewport = data->viewport_copy;
   3.120 -            D3D_UpdateViewport(renderer);
   3.121 -        }
   3.122 -        return 0;
   3.123 -    }
   3.124 -    if (renderer != texture->renderer) return -1;
   3.125 -
   3.126 -    if ( !data->renderTargetActive ) {
   3.127 -        data->viewport_copy = renderer->viewport;
   3.128 -    }
   3.129 -
   3.130 -    texturedata = (D3D_TextureData *) texture->driverdata;
   3.131 -    result = IDirect3DTexture9_GetSurfaceLevel(texturedata->texture, 0, &data->currentRenderTarget );
   3.132 -    if(FAILED(result)) {
   3.133 -        return -1;
   3.134 -    }
   3.135 -    result = IDirect3DDevice9_SetRenderTarget(data->device, 0, data->currentRenderTarget );
   3.136 -    if(FAILED(result)) {
   3.137 -        return -1;
   3.138 -    }
   3.139 -
   3.140 -    data->renderTargetActive = SDL_TRUE;
   3.141 -    renderer->viewport.x = 0;
   3.142 -    renderer->viewport.y = 0;
   3.143 -    renderer->viewport.w = texture->w;
   3.144 -    renderer->viewport.h = texture->h;
   3.145 -    D3D_UpdateViewport(renderer);
   3.146 -    return 0;
   3.147 -}
   3.148 -
   3.149 -static int
   3.150  D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
   3.151  {
   3.152      D3D_RenderData *renderdata = (D3D_RenderData *) renderer->driverdata;
   3.153 @@ -668,11 +592,10 @@
   3.154      } else
   3.155  #endif
   3.156      if (texture->access == SDL_TEXTUREACCESS_TARGET) {
   3.157 -        pool = D3DPOOL_DEFAULT;         // D3DPOOL_MANAGED does not work with usage=D3DUSAGE_RENDERTARGET
   3.158 +        /* D3DPOOL_MANAGED does not work with D3DUSAGE_RENDERTARGET */
   3.159 +        pool = D3DPOOL_DEFAULT;
   3.160          usage = D3DUSAGE_RENDERTARGET;
   3.161 -    }
   3.162 -    else
   3.163 -    {
   3.164 +    } else {
   3.165          pool = D3DPOOL_MANAGED;
   3.166          usage = 0;
   3.167      }
   3.168 @@ -811,6 +734,41 @@
   3.169  }
   3.170  
   3.171  static int
   3.172 +D3D_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture)
   3.173 +{
   3.174 +    D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
   3.175 +    D3D_TextureData *texturedata;
   3.176 +    HRESULT result;
   3.177 +
   3.178 +    D3D_ActivateRenderer(renderer);
   3.179 +
   3.180 +    /* Release the previous render target if it wasn't the default one */
   3.181 +    if (data->currentRenderTarget != NULL) {
   3.182 +        IDirect3DSurface9_Release(data->currentRenderTarget);
   3.183 +        data->currentRenderTarget = NULL;
   3.184 +    }
   3.185 +
   3.186 +    if (texture == NULL) {
   3.187 +        IDirect3DDevice9_SetRenderTarget(data->device, 0, data->defaultRenderTarget);
   3.188 +        return 0;
   3.189 +    }
   3.190 +
   3.191 +    texturedata = (D3D_TextureData *) texture->driverdata;
   3.192 +    result = IDirect3DTexture9_GetSurfaceLevel(texturedata->texture, 0, &data->currentRenderTarget);
   3.193 +    if(FAILED(result)) {
   3.194 +        D3D_SetError("GetSurfaceLevel()", result);
   3.195 +        return -1;
   3.196 +    }
   3.197 +    result = IDirect3DDevice9_SetRenderTarget(data->device, 0, data->currentRenderTarget);
   3.198 +    if(FAILED(result)) {
   3.199 +        D3D_SetError("SetRenderTarget()", result);
   3.200 +        return -1;
   3.201 +    }
   3.202 +
   3.203 +    return 0;
   3.204 +}
   3.205 +
   3.206 +static int
   3.207  D3D_RenderClear(SDL_Renderer * renderer)
   3.208  {
   3.209      D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
     4.1 --- a/src/render/opengl/SDL_render_gl.c	Sat Jan 21 22:14:38 2012 -0500
     4.2 +++ b/src/render/opengl/SDL_render_gl.c	Sat Jan 21 22:22:30 2012 -0500
     4.3 @@ -54,6 +54,7 @@
     4.4  static int GL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
     4.5                            const SDL_Rect * rect, void **pixels, int *pitch);
     4.6  static void GL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
     4.7 +static int GL_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture);
     4.8  static int GL_UpdateViewport(SDL_Renderer * renderer);
     4.9  static int GL_RenderClear(SDL_Renderer * renderer);
    4.10  static int GL_RenderDrawPoints(SDL_Renderer * renderer,
    4.11 @@ -66,7 +67,6 @@
    4.12                           const SDL_Rect * srcrect, const SDL_Rect * dstrect);
    4.13  static int GL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
    4.14                                 Uint32 pixel_format, void * pixels, int pitch);
    4.15 -static int GL_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture);
    4.16  static void GL_RenderPresent(SDL_Renderer * renderer);
    4.17  static void GL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture);
    4.18  static void GL_DestroyRenderer(SDL_Renderer * renderer);
    4.19 @@ -104,8 +104,6 @@
    4.20      
    4.21      SDL_bool GL_EXT_framebuffer_object_supported;
    4.22      GL_FBOList *framebuffers;
    4.23 -    SDL_Texture *renderTarget;
    4.24 -    SDL_Rect viewport_copy;
    4.25  
    4.26      /* OpenGL functions */
    4.27  #define SDL_PROC(ret,func,params) ret (APIENTRY *func) params;
    4.28 @@ -309,19 +307,19 @@
    4.29      renderer->UpdateTexture = GL_UpdateTexture;
    4.30      renderer->LockTexture = GL_LockTexture;
    4.31      renderer->UnlockTexture = GL_UnlockTexture;
    4.32 +    renderer->SetTargetTexture = GL_SetTargetTexture;
    4.33      renderer->UpdateViewport = GL_UpdateViewport;
    4.34      renderer->RenderClear = GL_RenderClear;
    4.35      renderer->RenderDrawPoints = GL_RenderDrawPoints;
    4.36      renderer->RenderDrawLines = GL_RenderDrawLines;
    4.37      renderer->RenderFillRects = GL_RenderFillRects;
    4.38      renderer->RenderCopy = GL_RenderCopy;
    4.39 -    renderer->SetTargetTexture = GL_SetTargetTexture;
    4.40      renderer->RenderReadPixels = GL_RenderReadPixels;
    4.41      renderer->RenderPresent = GL_RenderPresent;
    4.42      renderer->DestroyTexture = GL_DestroyTexture;
    4.43      renderer->DestroyRenderer = GL_DestroyRenderer;
    4.44      renderer->info = GL_RenderDriver.info;
    4.45 -    renderer->info.flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE;
    4.46 +    renderer->info.flags = SDL_RENDERER_ACCELERATED;
    4.47      renderer->driverdata = data;
    4.48      renderer->window = window;
    4.49  
    4.50 @@ -399,11 +397,11 @@
    4.51              SDL_GL_GetProcAddress("glFramebufferTexture2DEXT");
    4.52          data->glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC)
    4.53              SDL_GL_GetProcAddress("glBindFramebufferEXT");
    4.54 -       data->glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)
    4.55 +        data->glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)
    4.56              SDL_GL_GetProcAddress("glCheckFramebufferStatusEXT");
    4.57 +        renderer->info.flags |= SDL_RENDERER_TARGETTEXTURE;
    4.58      }
    4.59      data->framebuffers = NULL;
    4.60 -    data->renderTarget = NULL;
    4.61  
    4.62      /* Set up parameters for rendering */
    4.63      GL_ResetState(renderer);
    4.64 @@ -466,74 +464,6 @@
    4.65  }
    4.66  
    4.67  static int
    4.68 -GL_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture)
    4.69 -{
    4.70 -    GL_RenderData *data = (GL_RenderData *) renderer->driverdata;    
    4.71 -    
    4.72 -    GL_TextureData *texturedata;
    4.73 -    GLenum status;
    4.74 -
    4.75 -    if (!renderer) return -1;
    4.76 -    GL_ActivateRenderer(renderer);
    4.77 -    
    4.78 -    if (! data->GL_EXT_framebuffer_object_supported) {
    4.79 -        SDL_Unsupported();
    4.80 -        return -1;
    4.81 -    }
    4.82 -    
    4.83 -    if (texture == NULL) {
    4.84 -        if (data->renderTarget != NULL) {
    4.85 -            data->renderTarget = NULL;
    4.86 -            renderer->viewport = data->viewport_copy;
    4.87 -            data->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
    4.88 -            data->glMatrixMode(GL_PROJECTION);
    4.89 -            data->glLoadIdentity();
    4.90 -            data->glMatrixMode(GL_MODELVIEW);
    4.91 -            data->glLoadIdentity();
    4.92 -            data->glViewport(renderer->viewport.x, renderer->viewport.y, renderer->viewport.w, renderer->viewport.h);
    4.93 -            data->glOrtho(0.0, (GLdouble) renderer->viewport.w, (GLdouble) renderer->viewport.h, 0.0, 0.0, 1.0);
    4.94 -        }
    4.95 -        return 0;
    4.96 -    }
    4.97 -    if (renderer != texture->renderer) return -1;
    4.98 -    if (data->renderTarget==NULL) {
    4.99 -        // Keep a copy of the default viewport to restore when texture==NULL
   4.100 -        data->viewport_copy = renderer->viewport;
   4.101 -    }
   4.102 -    
   4.103 -    
   4.104 -    texturedata = (GL_TextureData *) texture->driverdata;
   4.105 -    if (!texturedata) {
   4.106 -        if (texture->native && texture->native->driverdata) {
   4.107 -            texture = texture->native;
   4.108 -            texturedata = texture->driverdata;
   4.109 -        }
   4.110 -        else return -1;
   4.111 -    }
   4.112 -    data->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, texturedata->fbo->FBO);
   4.113 -    /* TODO: check if texture pixel format allows this operation */
   4.114 -    data->glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, texturedata->type, texturedata->texture, 0);
   4.115 -    /* Check FBO status */
   4.116 -    status = data->glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
   4.117 -    if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
   4.118 -        return -1;
   4.119 -    }
   4.120 -
   4.121 -    data->renderTarget = texture;
   4.122 -    renderer->viewport.x = 0;
   4.123 -    renderer->viewport.y = 0;
   4.124 -    renderer->viewport.w = texture->w;
   4.125 -    renderer->viewport.h = texture->h;
   4.126 -    data->glMatrixMode(GL_PROJECTION);
   4.127 -    data->glLoadIdentity();
   4.128 -    data->glOrtho(0.0, (GLdouble) texture->w, 0.0, (GLdouble) texture->h, 0.0, 1.0);
   4.129 -    data->glMatrixMode(GL_MODELVIEW);
   4.130 -    data->glLoadIdentity();
   4.131 -    data->glViewport(0, 0, texture->w, texture->h);    
   4.132 -    return 0;
   4.133 -}
   4.134 -
   4.135 -static int
   4.136  GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
   4.137  {
   4.138      GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata;
   4.139 @@ -777,6 +707,33 @@
   4.140  }
   4.141  
   4.142  static int
   4.143 +GL_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture)
   4.144 +{
   4.145 +    GL_RenderData *data = (GL_RenderData *) renderer->driverdata;    
   4.146 +    GL_TextureData *texturedata;
   4.147 +    GLenum status;
   4.148 +
   4.149 +    GL_ActivateRenderer(renderer);
   4.150 +    
   4.151 +    if (texture == NULL) {
   4.152 +        data->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
   4.153 +        return 0;
   4.154 +    }
   4.155 +
   4.156 +    texturedata = (GL_TextureData *) texture->driverdata;
   4.157 +    data->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, texturedata->fbo->FBO);
   4.158 +    /* TODO: check if texture pixel format allows this operation */
   4.159 +    data->glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, texturedata->type, texturedata->texture, 0);
   4.160 +    /* Check FBO status */
   4.161 +    status = data->glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
   4.162 +    if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
   4.163 +        SDL_SetError("glFramebufferTexture2DEXT() failed");
   4.164 +        return -1;
   4.165 +    }
   4.166 +    return 0;
   4.167 +}
   4.168 +
   4.169 +static int
   4.170  GL_UpdateViewport(SDL_Renderer * renderer)
   4.171  {
   4.172      GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
   4.173 @@ -791,10 +748,19 @@
   4.174  
   4.175      data->glMatrixMode(GL_PROJECTION);
   4.176      data->glLoadIdentity();
   4.177 -    data->glOrtho((GLdouble) 0,
   4.178 -                  (GLdouble) renderer->viewport.w,
   4.179 -                  (GLdouble) renderer->viewport.h,
   4.180 -                  (GLdouble) 0, 0.0, 1.0);
   4.181 +    if (renderer->target) {
   4.182 +        data->glOrtho((GLdouble) 0,
   4.183 +                      (GLdouble) renderer->viewport.w,
   4.184 +                      (GLdouble) 0,
   4.185 +                      (GLdouble) renderer->viewport.h,
   4.186 +                       0.0, 1.0);
   4.187 +    } else {
   4.188 +        data->glOrtho((GLdouble) 0,
   4.189 +                      (GLdouble) renderer->viewport.w,
   4.190 +                      (GLdouble) renderer->viewport.h,
   4.191 +                      (GLdouble) 0,
   4.192 +                       0.0, 1.0);
   4.193 +    }
   4.194      return 0;
   4.195  }
   4.196  
     5.1 --- a/src/render/opengles/SDL_render_gles.c	Sat Jan 21 22:14:38 2012 -0500
     5.2 +++ b/src/render/opengles/SDL_render_gles.c	Sat Jan 21 22:22:30 2012 -0500
     5.3 @@ -56,6 +56,8 @@
     5.4                              const SDL_Rect * rect, void **pixels, int *pitch);
     5.5  static void GLES_UnlockTexture(SDL_Renderer * renderer,
     5.6                                 SDL_Texture * texture);
     5.7 +static int GLES_SetTargetTexture(SDL_Renderer * renderer,
     5.8 +                                 SDL_Texture * texture);
     5.9  static int GLES_UpdateViewport(SDL_Renderer * renderer);
    5.10  static int GLES_RenderClear(SDL_Renderer * renderer);
    5.11  static int GLES_RenderDrawPoints(SDL_Renderer * renderer,
    5.12 @@ -73,7 +75,6 @@
    5.13  static void GLES_DestroyTexture(SDL_Renderer * renderer,
    5.14                                  SDL_Texture * texture);
    5.15  static void GLES_DestroyRenderer(SDL_Renderer * renderer);
    5.16 -static int GLES_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture);
    5.17  
    5.18  typedef struct GLES_FBOList GLES_FBOList;
    5.19  
    5.20 @@ -110,8 +111,6 @@
    5.21  #undef SDL_PROC
    5.22      SDL_bool GL_OES_framebuffer_object_supported;
    5.23      GLES_FBOList *framebuffers;
    5.24 -    SDL_Texture *renderTarget;
    5.25 -    SDL_Rect viewport_copy;
    5.26  
    5.27      SDL_bool useDrawTexture;
    5.28      SDL_bool GL_OES_draw_texture_supported;
    5.29 @@ -257,71 +256,6 @@
    5.30      data->glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    5.31  }
    5.32  
    5.33 -static int
    5.34 -GLES_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture)
    5.35 -{
    5.36 -    GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
    5.37 -    int w, h;
    5.38 -    GLES_TextureData *texturedata = NULL;
    5.39 -    GLenum status;
    5.40 -
    5.41 -    if (!renderer) return -1;
    5.42 -    GLES_ActivateRenderer(renderer);
    5.43 -    if (! data->GL_OES_framebuffer_object_supported) {
    5.44 -        SDL_Unsupported();
    5.45 -        return -1;
    5.46 -    }
    5.47 -
    5.48 -    if (texture == NULL) {
    5.49 -        if (data->renderTarget != NULL) {
    5.50 -            data->renderTarget = NULL;
    5.51 -            renderer->viewport = data->viewport_copy;
    5.52 -            data->glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
    5.53 -            data->glMatrixMode(GL_PROJECTION);
    5.54 -            data->glLoadIdentity();
    5.55 -            data->glMatrixMode(GL_MODELVIEW);
    5.56 -            data->glLoadIdentity();
    5.57 -            data->glViewport(renderer->viewport.x, renderer->viewport.y, renderer->viewport.w, renderer->viewport.h);
    5.58 -            data->glOrthof(0.0, (GLfloat) renderer->viewport.w, (GLfloat) renderer->viewport.h, 0.0, 0.0, 1.0);
    5.59 -        }
    5.60 -        return 0;
    5.61 -    }
    5.62 -
    5.63 -    if (renderer != texture->renderer) return -1;
    5.64 -    if (data->renderTarget==NULL) {
    5.65 -        // Keep a copy of the default viewport to restore when texture==NULL
    5.66 -        data->viewport_copy = renderer->viewport;
    5.67 -    }
    5.68 -    texturedata = (GLES_TextureData *) texture->driverdata;
    5.69 -    if (!texturedata) {
    5.70 -        if (texture->native && texture->native->driverdata) {
    5.71 -            texture = texture->native;
    5.72 -            texturedata = texture->driverdata;
    5.73 -        }
    5.74 -        else return -1;
    5.75 -    }
    5.76 -    data->glBindFramebufferOES(GL_FRAMEBUFFER_OES, texturedata->fbo->FBO);
    5.77 -    /* TODO: check if texture pixel format allows this operation */
    5.78 -    data->glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, texturedata->type, texturedata->texture, 0);
    5.79 -    /* Check FBO status */
    5.80 -    status = data->glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
    5.81 -    if (status != GL_FRAMEBUFFER_COMPLETE_OES) {
    5.82 -        return -1;
    5.83 -    }
    5.84 -    data->renderTarget = texture;
    5.85 -    renderer->viewport.x = 0;
    5.86 -    renderer->viewport.y = 0;
    5.87 -    renderer->viewport.w = texture->w;
    5.88 -    renderer->viewport.h = texture->h;
    5.89 -    data->glMatrixMode(GL_PROJECTION);
    5.90 -    data->glLoadIdentity();
    5.91 -    data->glOrthof(0.0, (GLfloat) texture->w, 0.0, (GLfloat) texture->h, 0.0, 1.0);
    5.92 -    data->glMatrixMode(GL_MODELVIEW);
    5.93 -    data->glLoadIdentity();
    5.94 -    data->glViewport(0, 0, texture->w, texture->h);
    5.95 -    return 0;
    5.96 -}
    5.97 -
    5.98  SDL_Renderer *
    5.99  GLES_CreateRenderer(SDL_Window * window, Uint32 flags)
   5.100  {
   5.101 @@ -361,6 +295,7 @@
   5.102      renderer->UpdateTexture = GLES_UpdateTexture;
   5.103      renderer->LockTexture = GLES_LockTexture;
   5.104      renderer->UnlockTexture = GLES_UnlockTexture;
   5.105 +    renderer->SetTargetTexture = GLES_SetTargetTexture;
   5.106      renderer->UpdateViewport = GLES_UpdateViewport;
   5.107      renderer->RenderClear = GLES_RenderClear;
   5.108      renderer->RenderDrawPoints = GLES_RenderDrawPoints;
   5.109 @@ -372,10 +307,9 @@
   5.110      renderer->DestroyTexture = GLES_DestroyTexture;
   5.111      renderer->DestroyRenderer = GLES_DestroyRenderer;
   5.112      renderer->info = GLES_RenderDriver.info;
   5.113 -    renderer->info.flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE;
   5.114 +    renderer->info.flags = SDL_RENDERER_ACCELERATED;
   5.115      renderer->driverdata = data;
   5.116      renderer->window = window;
   5.117 -    renderer->SetTargetTexture = GLES_SetTargetTexture;
   5.118  
   5.119      data->context = SDL_GL_CreateContext(window);
   5.120      if (!data->context) {
   5.121 @@ -421,9 +355,9 @@
   5.122  
   5.123      if (SDL_GL_ExtensionSupported("GL_OES_framebuffer_object")) {
   5.124          data->GL_OES_framebuffer_object_supported = SDL_TRUE;
   5.125 +        renderer->info.flags |= SDL_RENDERER_TARGETTEXTURE;
   5.126      }
   5.127      data->framebuffers = NULL;
   5.128 -    data->renderTarget = NULL;
   5.129  
   5.130      /* Set up parameters for rendering */
   5.131      GLES_ResetState(renderer);
   5.132 @@ -641,6 +575,33 @@
   5.133  }
   5.134  
   5.135  static int
   5.136 +GLES_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture)
   5.137 +{
   5.138 +    GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
   5.139 +    GLES_TextureData *texturedata = NULL;
   5.140 +    GLenum status;
   5.141 +
   5.142 +    GLES_ActivateRenderer(renderer);
   5.143 +
   5.144 +    if (texture == NULL) {
   5.145 +        data->glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
   5.146 +        return 0;
   5.147 +    }
   5.148 +
   5.149 +    texturedata = (GLES_TextureData *) texture->driverdata;
   5.150 +    data->glBindFramebufferOES(GL_FRAMEBUFFER_OES, texturedata->fbo->FBO);
   5.151 +    /* TODO: check if texture pixel format allows this operation */
   5.152 +    data->glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, texturedata->type, texturedata->texture, 0);
   5.153 +    /* Check FBO status */
   5.154 +    status = data->glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
   5.155 +    if (status != GL_FRAMEBUFFER_COMPLETE_OES) {
   5.156 +        SDL_SetError("glFramebufferTexture2DOES() failed");
   5.157 +        return -1;
   5.158 +    }
   5.159 +    return 0;
   5.160 +}
   5.161 +
   5.162 +static int
   5.163  GLES_UpdateViewport(SDL_Renderer * renderer)
   5.164  {
   5.165      GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
   5.166 @@ -870,7 +831,7 @@
   5.167          SDL_Window *window = renderer->window;
   5.168  
   5.169          SDL_GetWindowSize(window, &w, &h);
   5.170 -        if (data->renderTarget != NULL) {
   5.171 +        if (renderer->target) {
   5.172              cropRect[0] = srcrect->x;
   5.173              cropRect[1] = srcrect->y;
   5.174              cropRect[2] = srcrect->w;
     6.1 --- a/src/render/opengles2/SDL_render_gles2.c	Sat Jan 21 22:14:38 2012 -0500
     6.2 +++ b/src/render/opengles2/SDL_render_gles2.c	Sat Jan 21 22:22:30 2012 -0500
     6.3 @@ -145,8 +145,6 @@
     6.4  #include "SDL_gles2funcs.h"
     6.5  #undef SDL_PROC
     6.6      GLES2_FBOList *framebuffers;
     6.7 -    SDL_Texture *renderTarget;
     6.8 -    SDL_Rect viewport_copy;
     6.9  
    6.10      int shader_format_count;
    6.11      GLenum *shader_formats;
    6.12 @@ -166,8 +164,8 @@
    6.13                                const SDL_WindowEvent *event);
    6.14  static int GLES2_UpdateViewport(SDL_Renderer * renderer);
    6.15  static void GLES2_DestroyRenderer(SDL_Renderer *renderer);
    6.16 +static int GLES2_SetOrthographicProjection(SDL_Renderer *renderer);
    6.17  
    6.18 -static int GLES2_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture);
    6.19  
    6.20  static SDL_GLContext SDL_CurrentContext = NULL;
    6.21  
    6.22 @@ -329,6 +327,7 @@
    6.23  static void GLES2_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture);
    6.24  static int GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect,
    6.25                                 const void *pixels, int pitch);
    6.26 +static int GLES2_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture);
    6.27  
    6.28  static GLenum
    6.29  GetScaleQuality(void)
    6.30 @@ -533,6 +532,33 @@
    6.31      return 0;
    6.32  }
    6.33  
    6.34 +static int
    6.35 +GLES2_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture)
    6.36 +{
    6.37 +    GLES2_DriverContext *data = (GLES2_DriverContext *) renderer->driverdata;
    6.38 +    GLES2_TextureData *texturedata = NULL;
    6.39 +    GLenum status;
    6.40 +
    6.41 +    if (texture == NULL) {
    6.42 +        data->glBindFramebuffer(GL_FRAMEBUFFER, 0);
    6.43 +    } else {
    6.44 +        texturedata = (GLES2_TextureData *) texture->driverdata;
    6.45 +        data->glBindFramebuffer(GL_FRAMEBUFFER, texturedata->fbo->FBO);
    6.46 +        /* TODO: check if texture pixel format allows this operation */
    6.47 +        data->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texturedata->texture_type, texturedata->texture, 0);
    6.48 +        /* Check FBO status */
    6.49 +        status = data->glCheckFramebufferStatus(GL_FRAMEBUFFER);
    6.50 +        if (status != GL_FRAMEBUFFER_COMPLETE) {
    6.51 +            SDL_SetError("glFramebufferTexture2D() failed");
    6.52 +            return -1;
    6.53 +        }
    6.54 +    }
    6.55 +    if (data->current_program) {
    6.56 +        GLES2_SetOrthographicProjection(renderer);
    6.57 +    }
    6.58 +    return 0;
    6.59 +}
    6.60 +
    6.61  /*************************************************************************************************
    6.62   * Shader management functions                                                                   *
    6.63   *************************************************************************************************/
    6.64 @@ -546,7 +572,6 @@
    6.65                                                     SDL_BlendMode blendMode);
    6.66  static int GLES2_SelectProgram(SDL_Renderer *renderer, GLES2_ImageSource source,
    6.67                                 SDL_BlendMode blendMode);
    6.68 -static int GLES2_SetOrthographicProjection(SDL_Renderer *renderer);
    6.69  
    6.70  static GLES2_ProgramCacheEntry *
    6.71  GLES2_CacheProgram(SDL_Renderer *renderer, GLES2_ShaderCacheEntry *vertex,
    6.72 @@ -1128,13 +1153,13 @@
    6.73  
    6.74      /* Activate an appropriate shader and set the projection matrix */
    6.75      blendMode = texture->blendMode;
    6.76 -    if (rdata->renderTarget!=NULL) {
    6.77 +    if (renderer->target) {
    6.78          /* Check if we need to do color mapping between the source and render target textures */
    6.79 -        if (rdata->renderTarget->format != texture->format) {
    6.80 +        if (renderer->target->format != texture->format) {
    6.81              switch (texture->format)
    6.82              {
    6.83              case SDL_PIXELFORMAT_ABGR8888:
    6.84 -                switch (rdata->renderTarget->format)
    6.85 +                switch (renderer->target->format)
    6.86                  {
    6.87                      case SDL_PIXELFORMAT_ARGB8888:
    6.88                      case SDL_PIXELFORMAT_RGB888:
    6.89 @@ -1146,7 +1171,7 @@
    6.90                  }
    6.91                  break;
    6.92              case SDL_PIXELFORMAT_ARGB8888:
    6.93 -                switch (rdata->renderTarget->format)
    6.94 +                switch (renderer->target->format)
    6.95                  {
    6.96                      case SDL_PIXELFORMAT_ABGR8888:
    6.97                      case SDL_PIXELFORMAT_BGR888:
    6.98 @@ -1158,7 +1183,7 @@
    6.99                  }
   6.100                  break;
   6.101              case SDL_PIXELFORMAT_BGR888:
   6.102 -                switch (rdata->renderTarget->format)
   6.103 +                switch (renderer->target->format)
   6.104                  {
   6.105                      case SDL_PIXELFORMAT_ABGR8888:
   6.106                          sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR;
   6.107 @@ -1172,7 +1197,7 @@
   6.108                  }
   6.109                  break;
   6.110              case SDL_PIXELFORMAT_RGB888:
   6.111 -                switch (rdata->renderTarget->format)
   6.112 +                switch (renderer->target->format)
   6.113                  {
   6.114                      case SDL_PIXELFORMAT_ABGR8888:
   6.115                          sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
   6.116 @@ -1230,7 +1255,7 @@
   6.117      GLES2_SetTexCoords(rdata, SDL_TRUE);
   6.118  
   6.119      /* Emit the textured quad */
   6.120 -    if (rdata->renderTarget!=NULL) {
   6.121 +    if (renderer->target) {
   6.122          // Flip the texture vertically to compensate for the inversion it'll be subjected to later when it's rendered to the screen
   6.123          vertices[0] = (GLfloat)dstrect->x;
   6.124          vertices[1] = (GLfloat)renderer->viewport.h-dstrect->y;
   6.125 @@ -1356,60 +1381,6 @@
   6.126      rdata->glDisableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD);
   6.127  }
   6.128  
   6.129 -static int
   6.130 -GLES2_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture)
   6.131 -{
   6.132 -    GLES2_DriverContext *data = (GLES2_DriverContext *) renderer->driverdata;
   6.133 -    GLES2_TextureData *texturedata = NULL;
   6.134 -    GLenum status;
   6.135 -    SDL_BlendMode blendMode;
   6.136 -
   6.137 -    if (!renderer) return -1;
   6.138 -
   6.139 -    blendMode = texture->blendMode;
   6.140 -    if (texture == NULL) {
   6.141 -        if (data->renderTarget!=NULL) {
   6.142 -            data->glBindFramebuffer(GL_FRAMEBUFFER, 0);
   6.143 -            renderer->viewport = data->viewport_copy;
   6.144 -            data->renderTarget = NULL;
   6.145 -            data->glViewport(renderer->viewport.x, renderer->viewport.y, renderer->viewport.w, renderer->viewport.h);
   6.146 -            if(data->current_program) GLES2_SetOrthographicProjection(renderer);
   6.147 -        }
   6.148 -        return 0;
   6.149 -    }
   6.150 -    if (renderer != texture->renderer) return -1;
   6.151 -    if (data->renderTarget==NULL) {
   6.152 -        // Keep a copy of the default viewport to restore when texture==NULL
   6.153 -        data->viewport_copy = renderer->viewport;
   6.154 -    }
   6.155 -
   6.156 -    texturedata = (GLES2_TextureData *) texture->driverdata;
   6.157 -    if (!texturedata) {
   6.158 -        if (texture->native && texture->native->driverdata) {
   6.159 -            texture = texture->native;
   6.160 -            texturedata = texture->driverdata;
   6.161 -        }
   6.162 -        else return -1;
   6.163 -    }
   6.164 -    data->glBindFramebuffer(GL_FRAMEBUFFER, texturedata->fbo->FBO);
   6.165 -    /* TODO: check if texture pixel format allows this operation */
   6.166 -    data->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texturedata->texture_type, texturedata->texture, 0);
   6.167 -    /* Check FBO status */
   6.168 -    status = data->glCheckFramebufferStatus(GL_FRAMEBUFFER);
   6.169 -    if (status != GL_FRAMEBUFFER_COMPLETE) {
   6.170 -        return -1;
   6.171 -    }
   6.172 -    
   6.173 -    renderer->viewport.x = 0;
   6.174 -    renderer->viewport.y = 0;
   6.175 -    renderer->viewport.w = texture->w;
   6.176 -    renderer->viewport.h = texture->h;
   6.177 -    data->renderTarget = texture;
   6.178 -    data->glViewport(0, 0, texture->w, texture->h);
   6.179 -    if(data->current_program) GLES2_SetOrthographicProjection(renderer);
   6.180 -    return 0;
   6.181 -}
   6.182 -
   6.183  static SDL_Renderer *
   6.184  GLES2_CreateRenderer(SDL_Window *window, Uint32 flags)
   6.185  {
   6.186 @@ -1511,7 +1482,6 @@
   6.187  #endif /* ZUNE_HD */
   6.188  
   6.189      rdata->framebuffers = NULL;
   6.190 -    rdata->renderTarget = NULL;
   6.191  
   6.192      /* Populate the function pointers for the module */
   6.193      renderer->WindowEvent         = &GLES2_WindowEvent;
   6.194 @@ -1519,6 +1489,7 @@
   6.195      renderer->UpdateTexture       = &GLES2_UpdateTexture;
   6.196      renderer->LockTexture         = &GLES2_LockTexture;
   6.197      renderer->UnlockTexture       = &GLES2_UnlockTexture;
   6.198 +    renderer->SetTargetTexture    = &GLES2_SetTargetTexture;
   6.199      renderer->UpdateViewport      = &GLES2_UpdateViewport;
   6.200      renderer->RenderClear         = &GLES2_RenderClear;
   6.201      renderer->RenderDrawPoints    = &GLES2_RenderDrawPoints;
   6.202 @@ -1529,7 +1500,6 @@
   6.203      renderer->RenderPresent       = &GLES2_RenderPresent;
   6.204      renderer->DestroyTexture      = &GLES2_DestroyTexture;
   6.205      renderer->DestroyRenderer     = &GLES2_DestroyRenderer;
   6.206 -    renderer->SetTargetTexture    = &GLES2_SetTargetTexture;
   6.207  
   6.208      GLES2_ResetState(renderer);
   6.209  
     7.1 --- a/src/render/software/SDL_render_sw.c	Sat Jan 21 22:14:38 2012 -0500
     7.2 +++ b/src/render/software/SDL_render_sw.c	Sat Jan 21 22:22:30 2012 -0500
     7.3 @@ -51,6 +51,7 @@
     7.4  static int SW_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
     7.5                            const SDL_Rect * rect, void **pixels, int *pitch);
     7.6  static void SW_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
     7.7 +static int SW_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture);
     7.8  static int SW_UpdateViewport(SDL_Renderer * renderer);
     7.9  static int SW_RenderClear(SDL_Renderer * renderer);
    7.10  static int SW_RenderDrawPoints(SDL_Renderer * renderer,
    7.11 @@ -72,7 +73,7 @@
    7.12      SW_CreateRenderer,
    7.13      {
    7.14       "software",
    7.15 -     SDL_RENDERER_SOFTWARE,
    7.16 +     SDL_RENDERER_SOFTWARE | SDL_RENDERER_TARGETTEXTURE,
    7.17       8,
    7.18       {
    7.19        SDL_PIXELFORMAT_RGB555,
    7.20 @@ -91,6 +92,7 @@
    7.21  typedef struct
    7.22  {
    7.23      SDL_Surface *surface;
    7.24 +    SDL_Surface *window;
    7.25  } SW_RenderData;
    7.26  
    7.27  
    7.28 @@ -100,7 +102,10 @@
    7.29      SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
    7.30  
    7.31      if (!data->surface) {
    7.32 -        data->surface = SDL_GetWindowSurface(renderer->window);
    7.33 +        data->surface = data->window;
    7.34 +    }
    7.35 +    if (!data->surface) {
    7.36 +        data->surface = data->window = SDL_GetWindowSurface(renderer->window);
    7.37  
    7.38          SW_UpdateViewport(renderer);
    7.39      }
    7.40 @@ -140,8 +145,8 @@
    7.41      renderer->UpdateTexture = SW_UpdateTexture;
    7.42      renderer->LockTexture = SW_LockTexture;
    7.43      renderer->UnlockTexture = SW_UnlockTexture;
    7.44 +    renderer->SetTargetTexture = SW_SetTargetTexture;
    7.45      renderer->UpdateViewport = SW_UpdateViewport;
    7.46 -    renderer->DestroyTexture = SW_DestroyTexture;
    7.47      renderer->RenderClear = SW_RenderClear;
    7.48      renderer->RenderDrawPoints = SW_RenderDrawPoints;
    7.49      renderer->RenderDrawLines = SW_RenderDrawLines;
    7.50 @@ -149,6 +154,7 @@
    7.51      renderer->RenderCopy = SW_RenderCopy;
    7.52      renderer->RenderReadPixels = SW_RenderReadPixels;
    7.53      renderer->RenderPresent = SW_RenderPresent;
    7.54 +    renderer->DestroyTexture = SW_DestroyTexture;
    7.55      renderer->DestroyRenderer = SW_DestroyRenderer;
    7.56      renderer->info = SW_RenderDriver.info;
    7.57      renderer->driverdata = data;
    7.58 @@ -277,6 +283,19 @@
    7.59  }
    7.60  
    7.61  static int
    7.62 +SW_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture)
    7.63 +{
    7.64 +    SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
    7.65 +
    7.66 +    if (texture ) {
    7.67 +        data->surface = (SDL_Surface *) texture->driverdata;
    7.68 +    } else {
    7.69 +        data->surface = data->window;
    7.70 +    }
    7.71 +    return 0;
    7.72 +}
    7.73 +
    7.74 +static int
    7.75  SW_UpdateViewport(SDL_Renderer * renderer)
    7.76  {
    7.77      SW_RenderData *data = (SW_RenderData *) renderer->driverdata;