We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 3406

Summary: Fix Reading Pixels from a SDL_TEXTUREACCESS_TARGET Texture
Product: SDL Reporter: ancientcc
Component: renderAssignee: Sam Lantinga <slouken>
Status: RESOLVED FIXED QA Contact: Sam Lantinga <slouken>
Severity: normal    
Priority: P2 CC: sylvain.becker
Version: HG 2.1   
Hardware: All   
OS: All   
Attachments: Fix when use openGL

Description ancientcc 2016-08-09 13:51:38 UTC
Created attachment 2548 [details]
Fix when use openGL

If use SDL_RenderReadPixels from SDL_TEXTUREACCESS_TARGET, will be fail. 

Attachment can solve it when Render with OpenGL. On the other handle, https://github.com/freeors/SDL/blob/master/SDL2-2.0.4/src/render/opengles2/SDL_render_gles2.c is responsing to OpenGL ES2.
Comment 1 Sam Lantinga 2016-10-01 20:11:22 UTC
Can you please try with the latest SDL snapshot?
http://www.libsdl.org/tmp/SDL-2.0.zip
Comment 2 Sylvain 2017-11-09 14:55:27 UTC
I tried and I mark this as fixed as it worked.

This was fixed by https://hg.libsdl.org/SDL/rev/b8ca95a8eea9

The provided file is based on SDL 2.0.4 and the diff is:

diff -r e12c38730512 src/render/opengl/SDL_render_gl.c
--- a/src/render/opengl/SDL_render_gl.c	Sat Jan 02 11:17:06 2016 -0800
+++ b/src/render/opengl/SDL_render_gl.c	Thu Nov 09 12:55:15 2017 +0100
@@ -1420,13 +1420,20 @@
 
     GL_ActivateRenderer(renderer);
 
-    temp_pitch = rect->w * SDL_BYTESPERPIXEL(temp_format);
-    temp_pixels = SDL_malloc(rect->h * temp_pitch);
-    if (!temp_pixels) {
-        return SDL_OutOfMemory();
+	if (renderer->target) {
+		// when target, its format and row rang is decided by app.
+		// only read data, let app process format and row rang.
+        temp_pitch = pitch;
+        temp_pixels = pixels;
+        temp_format = pixel_format;
+    } else {
+	    temp_pitch = rect->w * SDL_BYTESPERPIXEL(temp_format);
+        temp_pixels = SDL_malloc(rect->h * temp_pitch);
+        if (!temp_pixels) {
+            return SDL_OutOfMemory();
+        }
     }
-
-    convert_format(data, temp_format, &internalFormat, &format, &type);
+	convert_format(data, temp_format, &internalFormat, &format, &type);
 
     SDL_GetRendererOutputSize(renderer, &w, &h);
 
@@ -1434,7 +1441,7 @@
     data->glPixelStorei(GL_PACK_ROW_LENGTH,
                         (temp_pitch / SDL_BYTESPERPIXEL(temp_format)));
 
-    data->glReadPixels(rect->x, (h-rect->y)-rect->h, rect->w, rect->h,
+    data->glReadPixels(rect->x, renderer->target? rect->y: (h-rect->y)-rect->h, rect->w, rect->h,
                        format, type, temp_pixels);
 
     if (GL_CheckError("glReadPixels()", renderer) < 0) {
@@ -1442,6 +1449,10 @@
         return -1;
     }
 
+	if (renderer->target) {
+        return 0;
+    }
+
     /* Flip the rows to be top-down */
     length = rect->w * SDL_BYTESPERPIXEL(temp_format);
     src = (Uint8*)temp_pixels + (rect->h-1)*temp_pitch;