Work in progress on implementation of SDL_RenderReadPixels() and SDL_RenderWritePixels(), code untested.
--HG-- extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%404163
This commit is contained in:
parent
15e287332f
commit
0e8fa16511
4 changed files with 203 additions and 0 deletions
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue