Work in progress on implementation of SDL_RenderReadPixels() and SDL_RenderWritePixels(), code untested.
authorSam Lantinga <slouken@libsdl.org>
Mon, 09 Nov 2009 05:20:11 +0000
changeset 342736cf454ba065
parent 3426 ee0178f1c507
child 3428 78475292e059
Work in progress on implementation of SDL_RenderReadPixels() and SDL_RenderWritePixels(), code untested.
src/video/SDL_renderer_sw.c
src/video/SDL_sysvideo.h
src/video/SDL_video.c
src/video/win32/SDL_d3drender.c
     1.1 --- a/src/video/SDL_renderer_sw.c	Mon Nov 09 04:13:51 2009 +0000
     1.2 +++ b/src/video/SDL_renderer_sw.c	Mon Nov 09 05:20:11 2009 +0000
     1.3 @@ -65,6 +65,10 @@
     1.4  static int SW_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect);
     1.5  static int SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
     1.6                           const SDL_Rect * srcrect, const SDL_Rect * dstrect);
     1.7 +static int SW_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
     1.8 +                               void * pixels, int pitch);
     1.9 +static int SW_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect,
    1.10 +                                const void * pixels, int pitch);
    1.11  static void SW_RenderPresent(SDL_Renderer * renderer);
    1.12  static void SW_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture);
    1.13  static void SW_DestroyRenderer(SDL_Renderer * renderer);
    1.14 @@ -228,6 +232,8 @@
    1.15      renderer->RenderLine = SW_RenderLine;
    1.16      renderer->RenderFill = SW_RenderFill;
    1.17      renderer->RenderCopy = SW_RenderCopy;
    1.18 +    renderer->RenderReadPixels = SW_RenderReadPixels;
    1.19 +    renderer->RenderWritePixels = SW_RenderWritePixels;
    1.20      renderer->RenderPresent = SW_RenderPresent;
    1.21      renderer->DestroyRenderer = SW_DestroyRenderer;
    1.22      renderer->info.name = SW_RenderDriver.info.name;
    1.23 @@ -728,6 +734,76 @@
    1.24      return status;
    1.25  }
    1.26  
    1.27 +static int
    1.28 +SW_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
    1.29 +                    void * pixels, int pitch)
    1.30 +{
    1.31 +    SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
    1.32 +    const Uint8 *src;
    1.33 +    Uint8 *dst;
    1.34 +    int src_pitch, dst_pitch, w, h;
    1.35 +
    1.36 +    if (data->renderer->LockTexture(data->renderer,
    1.37 +                                    data->texture[data->current_texture],
    1.38 +                                    rect, 0, &data->surface.pixels,
    1.39 +                                    &data->surface.pitch) < 0) {
    1.40 +        return -1;
    1.41 +    }
    1.42 +
    1.43 +    src = data->surface.pixels;
    1.44 +    src_pitch = data->surface.pitch;
    1.45 +    dst = pixels;
    1.46 +    dst_pitch = pitch;
    1.47 +    h = rect->h;
    1.48 +    w = rect->w * data->surface.format->BytesPerPixel;
    1.49 +    while (h--) {
    1.50 +        SDL_memcpy(dst, src, w);
    1.51 +        src += src_pitch;
    1.52 +        dst += dst_pitch;
    1.53 +    }
    1.54 +
    1.55 +    data->renderer->UnlockTexture(data->renderer,
    1.56 +                                  data->texture[data->current_texture]);
    1.57 +    return 0;
    1.58 +}
    1.59 +
    1.60 +static int
    1.61 +SW_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect,
    1.62 +                     const void * pixels, int pitch)
    1.63 +{
    1.64 +    SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
    1.65 +    const Uint8 *src;
    1.66 +    Uint8 *dst;
    1.67 +    int src_pitch, dst_pitch, w, h;
    1.68 +
    1.69 +    if (data->renderer->info.flags & SDL_RENDERER_PRESENTCOPY) {
    1.70 +        SDL_AddDirtyRect(&data->dirty, rect);
    1.71 +    }
    1.72 +
    1.73 +    if (data->renderer->LockTexture(data->renderer,
    1.74 +                                    data->texture[data->current_texture],
    1.75 +                                    rect, 1, &data->surface.pixels,
    1.76 +                                    &data->surface.pitch) < 0) {
    1.77 +        return -1;
    1.78 +    }
    1.79 +
    1.80 +    src = pixels;
    1.81 +    src_pitch = pitch;
    1.82 +    dst = data->surface.pixels;
    1.83 +    dst_pitch = data->surface.pitch;
    1.84 +    h = rect->h;
    1.85 +    w = rect->w * data->surface.format->BytesPerPixel;
    1.86 +    while (h--) {
    1.87 +        SDL_memcpy(dst, src, w);
    1.88 +        src += src_pitch;
    1.89 +        dst += dst_pitch;
    1.90 +    }
    1.91 +
    1.92 +    data->renderer->UnlockTexture(data->renderer,
    1.93 +                                  data->texture[data->current_texture]);
    1.94 +    return 0;
    1.95 +}
    1.96 +
    1.97  static void
    1.98  SW_RenderPresent(SDL_Renderer * renderer)
    1.99  {
     2.1 --- a/src/video/SDL_sysvideo.h	Mon Nov 09 04:13:51 2009 +0000
     2.2 +++ b/src/video/SDL_sysvideo.h	Mon Nov 09 05:20:11 2009 +0000
     2.3 @@ -96,6 +96,10 @@
     2.4      int (*RenderFill) (SDL_Renderer * renderer, const SDL_Rect * rect);
     2.5      int (*RenderCopy) (SDL_Renderer * renderer, SDL_Texture * texture,
     2.6                         const SDL_Rect * srcrect, const SDL_Rect * dstrect);
     2.7 +    int (*RenderReadPixels) (SDL_Renderer * renderer, const SDL_Rect * rect,
     2.8 +                             void * pixels, int pitch);
     2.9 +    int (*RenderWritePixels) (SDL_Renderer * renderer, const SDL_Rect * rect,
    2.10 +                              const void * pixels, int pitch);
    2.11      void (*RenderPresent) (SDL_Renderer * renderer);
    2.12      void (*DestroyTexture) (SDL_Renderer * renderer, SDL_Texture * texture);
    2.13  
     3.1 --- a/src/video/SDL_video.c	Mon Nov 09 04:13:51 2009 +0000
     3.2 +++ b/src/video/SDL_video.c	Mon Nov 09 05:20:11 2009 +0000
     3.3 @@ -2486,6 +2486,82 @@
     3.4                                  &real_dstrect);
     3.5  }
     3.6  
     3.7 +int
     3.8 +SDL_RenderReadPixels(const SDL_Rect * rect, void * pixels, int pitch)
     3.9 +{
    3.10 +    SDL_Renderer *renderer;
    3.11 +    SDL_Window *window;
    3.12 +    SDL_Rect real_rect;
    3.13 +
    3.14 +    renderer = SDL_GetCurrentRenderer();
    3.15 +    if (!renderer) {
    3.16 +        return -1;
    3.17 +    }
    3.18 +    if (!renderer->RenderReadPixels) {
    3.19 +        SDL_Unsupported();
    3.20 +        return -1;
    3.21 +    }
    3.22 +    window = SDL_GetWindowFromID(renderer->window);
    3.23 +
    3.24 +    real_rect.x = 0;
    3.25 +    real_rect.y = 0;
    3.26 +    real_rect.w = window->w;
    3.27 +    real_rect.h = window->h;
    3.28 +    if (rect) {
    3.29 +        if (!SDL_IntersectRect(rect, &real_rect, &real_rect)) {
    3.30 +            return 0;
    3.31 +        }
    3.32 +        if (real_rect.y > rect->y) {
    3.33 +            pixels = (Uint8 *)pixels + pitch * (real_rect.y - rect->y);
    3.34 +        }
    3.35 +        if (real_rect.x > rect->x) {
    3.36 +            Uint32 format = SDL_CurrentDisplay.current_mode.format;
    3.37 +            int bpp = SDL_BYTESPERPIXEL(format);
    3.38 +            pixels = (Uint8 *)pixels + bpp * (real_rect.x - rect->x);
    3.39 +        }
    3.40 +    }
    3.41 +
    3.42 +    return renderer->RenderReadPixels(renderer, &real_rect, pixels, pitch);
    3.43 +}
    3.44 +
    3.45 +int
    3.46 +SDL_RenderWritePixels(const SDL_Rect * rect, const void * pixels, int pitch)
    3.47 +{
    3.48 +    SDL_Renderer *renderer;
    3.49 +    SDL_Window *window;
    3.50 +    SDL_Rect real_rect;
    3.51 +
    3.52 +    renderer = SDL_GetCurrentRenderer();
    3.53 +    if (!renderer) {
    3.54 +        return -1;
    3.55 +    }
    3.56 +    if (!renderer->RenderWritePixels) {
    3.57 +        SDL_Unsupported();
    3.58 +        return -1;
    3.59 +    }
    3.60 +    window = SDL_GetWindowFromID(renderer->window);
    3.61 +
    3.62 +    real_rect.x = 0;
    3.63 +    real_rect.y = 0;
    3.64 +    real_rect.w = window->w;
    3.65 +    real_rect.h = window->h;
    3.66 +    if (rect) {
    3.67 +        if (!SDL_IntersectRect(rect, &real_rect, &real_rect)) {
    3.68 +            return 0;
    3.69 +        }
    3.70 +        if (real_rect.y > rect->y) {
    3.71 +            pixels = (const Uint8 *)pixels + pitch * (real_rect.y - rect->y);
    3.72 +        }
    3.73 +        if (real_rect.x > rect->x) {
    3.74 +            Uint32 format = SDL_CurrentDisplay.current_mode.format;
    3.75 +            int bpp = SDL_BYTESPERPIXEL(format);
    3.76 +            pixels = (const Uint8 *)pixels + bpp * (real_rect.x - rect->x);
    3.77 +        }
    3.78 +    }
    3.79 +
    3.80 +    return renderer->RenderWritePixels(renderer, &real_rect, pixels, pitch);
    3.81 +}
    3.82 +
    3.83  void
    3.84  SDL_RenderPresent(void)
    3.85  {
     4.1 --- a/src/video/win32/SDL_d3drender.c	Mon Nov 09 04:13:51 2009 +0000
     4.2 +++ b/src/video/win32/SDL_d3drender.c	Mon Nov 09 05:20:11 2009 +0000
     4.3 @@ -72,6 +72,8 @@
     4.4  static int D3D_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect);
     4.5  static int D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
     4.6                            const SDL_Rect * srcrect, const SDL_Rect * dstrect);
     4.7 +static int D3D_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
     4.8 +                                void * pixels, int pitch);
     4.9  static void D3D_RenderPresent(SDL_Renderer * renderer);
    4.10  static void D3D_DestroyTexture(SDL_Renderer * renderer,
    4.11                                 SDL_Texture * texture);
    4.12 @@ -367,6 +369,7 @@
    4.13      renderer->RenderLine = D3D_RenderLine;
    4.14      renderer->RenderFill = D3D_RenderFill;
    4.15      renderer->RenderCopy = D3D_RenderCopy;
    4.16 +    renderer->RenderReadPixels = D3D_RenderReadPixels;
    4.17      renderer->RenderPresent = D3D_RenderPresent;
    4.18      renderer->DestroyTexture = D3D_DestroyTexture;
    4.19      renderer->DestroyRenderer = D3D_DestroyRenderer;
    4.20 @@ -1145,6 +1148,50 @@
    4.21      return 0;
    4.22  }
    4.23  
    4.24 +static int
    4.25 +D3D_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
    4.26 +                     void * pixels, int pitch)
    4.27 +{
    4.28 +    BYTE * pBytes;
    4.29 +    D3DLOCKED_RECT lockedRect;
    4.30 +    BYTE b, g, r, a;
    4.31 +    unsigned long index;
    4.32 +    int cur_mouse;
    4.33 +    int x, y;
    4.34 +
    4.35 +    LPDIRECT3DSURFACE9 backBuffer;
    4.36 +    LPDIRECT3DSURFACE9 pickOffscreenSurface;
    4.37 +    D3DSURFACE_DESC desc;
    4.38 +
    4.39 +    D3D_RenderData * data = (D3D_RenderData *) renderer->driverdata;
    4.40 +    
    4.41 +    IDirect3DDevice9_GetBackBuffer(data->device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backBuffer);
    4.42 +    
    4.43 +    
    4.44 +    IDirect3DSurface9_GetDesc(backBuffer, &desc);
    4.45 +
    4.46 +    IDirect3DDevice9_CreateOffscreenPlainSurface(data->device, desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &pickOffscreenSurface, NULL);
    4.47 +
    4.48 +    IDirect3DDevice9_GetRenderTargetData(data->device, backBuffer, pickOffscreenSurface);
    4.49 +
    4.50 +    IDirect3DSurface9_LockRect(pickOffscreenSurface, &lockedRect, NULL, D3DLOCK_READONLY);
    4.51 +    pBytes = (BYTE*)lockedRect.pBits;
    4.52 +    IDirect3DSurface9_UnlockRect(pickOffscreenSurface);
    4.53 +
    4.54 +    // just to debug -->
    4.55 +    cur_mouse = SDL_SelectMouse(-1);
    4.56 +    SDL_GetMouseState(cur_mouse, &x, &y);
    4.57 +    index = (x * 4 + (y * lockedRect.Pitch));
    4.58 +
    4.59 +    b = pBytes[index];
    4.60 +    g = pBytes[index+1];
    4.61 +    r = pBytes[index+2];
    4.62 +    a = pBytes[index+3];
    4.63 +    // <--
    4.64 +    
    4.65 +    return -1;
    4.66 +}
    4.67 +
    4.68  static void
    4.69  D3D_RenderPresent(SDL_Renderer * renderer)
    4.70  {