Work in progress on implementation of SDL_RenderReadPixels() and SDL_RenderWritePixels(), code untested.
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 {