SDL_RenderReadPixels() now returns a surface
Fixes https://github.com/libsdl-org/SDL/issues/8977
This commit is contained in:
parent
ab571633d1
commit
89b9d6cbdc
22 changed files with 216 additions and 310 deletions
|
@ -1457,74 +1457,58 @@ static int GL_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, vo
|
|||
return GL_CheckError("", renderer);
|
||||
}
|
||||
|
||||
static int GL_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect,
|
||||
Uint32 pixel_format, void *pixels, int pitch)
|
||||
static SDL_Surface *GL_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect)
|
||||
{
|
||||
GL_RenderData *data = (GL_RenderData *)renderer->driverdata;
|
||||
Uint32 temp_format = renderer->target ? renderer->target->format : SDL_PIXELFORMAT_ARGB8888;
|
||||
void *temp_pixels;
|
||||
int temp_pitch;
|
||||
Uint32 format = renderer->target ? renderer->target->format : SDL_PIXELFORMAT_ARGB8888;
|
||||
GLint internalFormat;
|
||||
GLenum format, type;
|
||||
Uint8 *src, *dst, *tmp;
|
||||
int w, h, length, rows;
|
||||
int status;
|
||||
GLenum targetFormat, type;
|
||||
int w, h;
|
||||
SDL_Surface *surface;
|
||||
|
||||
GL_ActivateRenderer(renderer);
|
||||
|
||||
if (!convert_format(temp_format, &internalFormat, &format, &type)) {
|
||||
return SDL_SetError("Texture format %s not supported by OpenGL",
|
||||
SDL_GetPixelFormatName(temp_format));
|
||||
if (!convert_format(format, &internalFormat, &targetFormat, &type)) {
|
||||
SDL_SetError("Texture format %s not supported by OpenGL", SDL_GetPixelFormatName(format));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (rect->w == 0 || rect->h == 0) {
|
||||
return 0; /* nothing to do. */
|
||||
}
|
||||
|
||||
temp_pitch = rect->w * SDL_BYTESPERPIXEL(temp_format);
|
||||
temp_pixels = SDL_malloc((size_t)rect->h * temp_pitch);
|
||||
if (!temp_pixels) {
|
||||
return -1;
|
||||
surface = SDL_CreateSurface(rect->w, rect->h, format);
|
||||
if (!surface) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SDL_GetCurrentRenderOutputSize(renderer, &w, &h);
|
||||
|
||||
data->glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
data->glPixelStorei(GL_PACK_ROW_LENGTH,
|
||||
(temp_pitch / SDL_BYTESPERPIXEL(temp_format)));
|
||||
data->glPixelStorei(GL_PACK_ROW_LENGTH, (surface->pitch / SDL_BYTESPERPIXEL(format)));
|
||||
|
||||
data->glReadPixels(rect->x, renderer->target ? rect->y : (h - rect->y) - rect->h,
|
||||
rect->w, rect->h, format, type, temp_pixels);
|
||||
rect->w, rect->h, targetFormat, type, surface->pixels);
|
||||
|
||||
if (GL_CheckError("glReadPixels()", renderer) < 0) {
|
||||
SDL_free(temp_pixels);
|
||||
return -1;
|
||||
SDL_DestroySurface(surface);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Flip the rows to be top-down if necessary */
|
||||
if (!renderer->target) {
|
||||
SDL_bool isstack;
|
||||
length = rect->w * SDL_BYTESPERPIXEL(temp_format);
|
||||
src = (Uint8 *)temp_pixels + (rect->h - 1) * temp_pitch;
|
||||
dst = (Uint8 *)temp_pixels;
|
||||
tmp = SDL_small_alloc(Uint8, length, &isstack);
|
||||
rows = rect->h / 2;
|
||||
int length = rect->w * SDL_BYTESPERPIXEL(format);
|
||||
Uint8 *src = (Uint8 *)surface->pixels + (rect->h - 1) * surface->pitch;
|
||||
Uint8 *dst = (Uint8 *)surface->pixels;
|
||||
Uint8 *tmp = SDL_small_alloc(Uint8, length, &isstack);
|
||||
int rows = rect->h / 2;
|
||||
while (rows--) {
|
||||
SDL_memcpy(tmp, dst, length);
|
||||
SDL_memcpy(dst, src, length);
|
||||
SDL_memcpy(src, tmp, length);
|
||||
dst += temp_pitch;
|
||||
src -= temp_pitch;
|
||||
dst += surface->pitch;
|
||||
src -= surface->pitch;
|
||||
}
|
||||
SDL_small_free(tmp, isstack);
|
||||
}
|
||||
|
||||
status = SDL_ConvertPixels(rect->w, rect->h,
|
||||
temp_format, temp_pixels, temp_pitch,
|
||||
pixel_format, pixels, pitch);
|
||||
SDL_free(temp_pixels);
|
||||
|
||||
return status;
|
||||
return surface;
|
||||
}
|
||||
|
||||
static int GL_RenderPresent(SDL_Renderer *renderer)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue