Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Commit

Permalink
Work in progress on implementation of SDL_RenderReadPixels() and SDL_…
Browse files Browse the repository at this point in the history
…RenderWritePixels(), code untested.
  • Loading branch information
slouken committed Nov 9, 2009
1 parent 896ca5b commit 7b8018c
Show file tree
Hide file tree
Showing 4 changed files with 203 additions and 0 deletions.
76 changes: 76 additions & 0 deletions src/video/SDL_renderer_sw.c
Expand Up @@ -65,6 +65,10 @@ static int SW_RenderLine(SDL_Renderer * renderer, int x1, int y1, int x2,
static int SW_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect);
static int SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * srcrect, const SDL_Rect * dstrect);
static int SW_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
void * pixels, int pitch);
static int SW_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect,
const void * pixels, int pitch);
static void SW_RenderPresent(SDL_Renderer * renderer);
static void SW_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture);
static void SW_DestroyRenderer(SDL_Renderer * renderer);
Expand Down Expand Up @@ -228,6 +232,8 @@ SW_CreateRenderer(SDL_Window * window, Uint32 flags)
renderer->RenderLine = SW_RenderLine;
renderer->RenderFill = SW_RenderFill;
renderer->RenderCopy = SW_RenderCopy;
renderer->RenderReadPixels = SW_RenderReadPixels;
renderer->RenderWritePixels = SW_RenderWritePixels;
renderer->RenderPresent = SW_RenderPresent;
renderer->DestroyRenderer = SW_DestroyRenderer;
renderer->info.name = SW_RenderDriver.info.name;
Expand Down Expand Up @@ -728,6 +734,76 @@ SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
return status;
}

static int
SW_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
void * pixels, int pitch)
{
SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
const Uint8 *src;
Uint8 *dst;
int src_pitch, dst_pitch, w, h;

if (data->renderer->LockTexture(data->renderer,
data->texture[data->current_texture],
rect, 0, &data->surface.pixels,
&data->surface.pitch) < 0) {
return -1;
}

src = data->surface.pixels;
src_pitch = data->surface.pitch;
dst = pixels;
dst_pitch = pitch;
h = rect->h;
w = rect->w * data->surface.format->BytesPerPixel;
while (h--) {
SDL_memcpy(dst, src, w);
src += src_pitch;
dst += dst_pitch;
}

data->renderer->UnlockTexture(data->renderer,
data->texture[data->current_texture]);
return 0;
}

static int
SW_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect,
const void * pixels, int pitch)
{
SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
const Uint8 *src;
Uint8 *dst;
int src_pitch, dst_pitch, w, h;

if (data->renderer->info.flags & SDL_RENDERER_PRESENTCOPY) {
SDL_AddDirtyRect(&data->dirty, rect);
}

if (data->renderer->LockTexture(data->renderer,
data->texture[data->current_texture],
rect, 1, &data->surface.pixels,
&data->surface.pitch) < 0) {
return -1;
}

src = pixels;
src_pitch = pitch;
dst = data->surface.pixels;
dst_pitch = data->surface.pitch;
h = rect->h;
w = rect->w * data->surface.format->BytesPerPixel;
while (h--) {
SDL_memcpy(dst, src, w);
src += src_pitch;
dst += dst_pitch;
}

data->renderer->UnlockTexture(data->renderer,
data->texture[data->current_texture]);
return 0;
}

static void
SW_RenderPresent(SDL_Renderer * renderer)
{
Expand Down
4 changes: 4 additions & 0 deletions src/video/SDL_sysvideo.h
Expand Up @@ -96,6 +96,10 @@ struct SDL_Renderer
int (*RenderFill) (SDL_Renderer * renderer, const SDL_Rect * rect);
int (*RenderCopy) (SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * srcrect, const SDL_Rect * dstrect);
int (*RenderReadPixels) (SDL_Renderer * renderer, const SDL_Rect * rect,
void * pixels, int pitch);
int (*RenderWritePixels) (SDL_Renderer * renderer, const SDL_Rect * rect,
const void * pixels, int pitch);
void (*RenderPresent) (SDL_Renderer * renderer);
void (*DestroyTexture) (SDL_Renderer * renderer, SDL_Texture * texture);

Expand Down
76 changes: 76 additions & 0 deletions src/video/SDL_video.c
Expand Up @@ -2486,6 +2486,82 @@ SDL_RenderCopy(SDL_TextureID textureID, const SDL_Rect * srcrect,
&real_dstrect);
}

int
SDL_RenderReadPixels(const SDL_Rect * rect, void * pixels, int pitch)
{
SDL_Renderer *renderer;
SDL_Window *window;
SDL_Rect real_rect;

renderer = SDL_GetCurrentRenderer();
if (!renderer) {
return -1;
}
if (!renderer->RenderReadPixels) {
SDL_Unsupported();
return -1;
}
window = SDL_GetWindowFromID(renderer->window);

real_rect.x = 0;
real_rect.y = 0;
real_rect.w = window->w;
real_rect.h = window->h;
if (rect) {
if (!SDL_IntersectRect(rect, &real_rect, &real_rect)) {
return 0;
}
if (real_rect.y > rect->y) {
pixels = (Uint8 *)pixels + pitch * (real_rect.y - rect->y);
}
if (real_rect.x > rect->x) {
Uint32 format = SDL_CurrentDisplay.current_mode.format;
int bpp = SDL_BYTESPERPIXEL(format);
pixels = (Uint8 *)pixels + bpp * (real_rect.x - rect->x);
}
}

return renderer->RenderReadPixels(renderer, &real_rect, pixels, pitch);
}

int
SDL_RenderWritePixels(const SDL_Rect * rect, const void * pixels, int pitch)
{
SDL_Renderer *renderer;
SDL_Window *window;
SDL_Rect real_rect;

renderer = SDL_GetCurrentRenderer();
if (!renderer) {
return -1;
}
if (!renderer->RenderWritePixels) {
SDL_Unsupported();
return -1;
}
window = SDL_GetWindowFromID(renderer->window);

real_rect.x = 0;
real_rect.y = 0;
real_rect.w = window->w;
real_rect.h = window->h;
if (rect) {
if (!SDL_IntersectRect(rect, &real_rect, &real_rect)) {
return 0;
}
if (real_rect.y > rect->y) {
pixels = (const Uint8 *)pixels + pitch * (real_rect.y - rect->y);
}
if (real_rect.x > rect->x) {
Uint32 format = SDL_CurrentDisplay.current_mode.format;
int bpp = SDL_BYTESPERPIXEL(format);
pixels = (const Uint8 *)pixels + bpp * (real_rect.x - rect->x);
}
}

return renderer->RenderWritePixels(renderer, &real_rect, pixels, pitch);
}

void
SDL_RenderPresent(void)
{
Expand Down
47 changes: 47 additions & 0 deletions src/video/win32/SDL_d3drender.c
Expand Up @@ -72,6 +72,8 @@ static int D3D_RenderLine(SDL_Renderer * renderer, int x1, int y1, int x2,
static int D3D_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect);
static int D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * srcrect, const SDL_Rect * dstrect);
static int D3D_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
void * pixels, int pitch);
static void D3D_RenderPresent(SDL_Renderer * renderer);
static void D3D_DestroyTexture(SDL_Renderer * renderer,
SDL_Texture * texture);
Expand Down Expand Up @@ -367,6 +369,7 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags)
renderer->RenderLine = D3D_RenderLine;
renderer->RenderFill = D3D_RenderFill;
renderer->RenderCopy = D3D_RenderCopy;
renderer->RenderReadPixels = D3D_RenderReadPixels;
renderer->RenderPresent = D3D_RenderPresent;
renderer->DestroyTexture = D3D_DestroyTexture;
renderer->DestroyRenderer = D3D_DestroyRenderer;
Expand Down Expand Up @@ -1145,6 +1148,50 @@ D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
return 0;
}

static int
D3D_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
void * pixels, int pitch)
{
BYTE * pBytes;
D3DLOCKED_RECT lockedRect;
BYTE b, g, r, a;
unsigned long index;
int cur_mouse;
int x, y;

LPDIRECT3DSURFACE9 backBuffer;
LPDIRECT3DSURFACE9 pickOffscreenSurface;
D3DSURFACE_DESC desc;

D3D_RenderData * data = (D3D_RenderData *) renderer->driverdata;

IDirect3DDevice9_GetBackBuffer(data->device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backBuffer);


IDirect3DSurface9_GetDesc(backBuffer, &desc);

IDirect3DDevice9_CreateOffscreenPlainSurface(data->device, desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &pickOffscreenSurface, NULL);

IDirect3DDevice9_GetRenderTargetData(data->device, backBuffer, pickOffscreenSurface);

IDirect3DSurface9_LockRect(pickOffscreenSurface, &lockedRect, NULL, D3DLOCK_READONLY);
pBytes = (BYTE*)lockedRect.pBits;
IDirect3DSurface9_UnlockRect(pickOffscreenSurface);

// just to debug -->
cur_mouse = SDL_SelectMouse(-1);
SDL_GetMouseState(cur_mouse, &x, &y);
index = (x * 4 + (y * lockedRect.Pitch));

b = pBytes[index];
g = pBytes[index+1];
r = pBytes[index+2];
a = pBytes[index+3];
// <--

return -1;
}

static void
D3D_RenderPresent(SDL_Renderer * renderer)
{
Expand Down

0 comments on commit 7b8018c

Please sign in to comment.