The SDL forums have moved to discourse.libsdl.org.
This is just a read-only archive of the previous forums, to keep old links working.


SDL Forum Index
SDL
Simple Directmedia Layer Forums
reading pixels from a TARGET texture
Sanette
Guest

Hi

I'm using a texture with SDL_TEXTUREACCESS_TARGET flag and I blit onto
this one (with SDL_RenderCopy) a number of other textures to finally
get my image.

Then I would like to get the final pixel array of that texture in
order to do more image processing by hand.

What is the best way to obtain this pixel array ?

thx
S.

_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
reading pixels from a TARGET texture
ancientli


Joined: 01 Jul 2015
Posts: 45
As far as I know, you need to change RenderReadPixels method of
SDL_Renderer. Below is my modified version.
----------------------------------------------------------------------------
------
OpenGL(function GL_RenderReadPixels):
https://github.com/freeors/SDL/blob/master/SDL2-2.0.4/src/render/opengl/SDL_
render_gl.c
OpenGL ES2(function GLES2_RenderReadPixels):
https://github.com/freeors/SDL/blob/master/SDL2-2.0.4/src/render/opengles2/S
DL_render_gles2.c

_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Re: reading pixels from a TARGET texture
rtrussell


Joined: 10 Feb 2016
Posts: 88
Sanette wrote:
What is the best way to obtain this pixel array ?

You can use SDL_RenderReadPixels but there are a couple of problems with that approach:
  • The API is buggy. For example with some renderers it will return the image upside-down!
  • The API can be very slow, especially if the target texture is significantly larger than the window.
To work around the first issue, and to ameliorate the second, I use this slightly more complex method (when the rectangle you want to read is no larger than the window):

Code:
int RenderReadPixels (SDL_Renderer* renderer, const SDL_Rect* rect,
                          Uint32 format, void* pixels, int pitch)
{
   int result ;
   SDL_Rect dst = {0, 0, rect->w, rect->h} ;
   SDL_Texture *tex = SDL_GetRenderTarget (renderer) ;
   SDL_SetRenderTarget (renderer, NULL) ;
   SDL_RenderCopy (renderer, tex, rect, &dst) ;
   result = SDL_RenderReadPixels (renderer, &dst, format, pixels, pitch) ;
   SDL_SetRenderTarget (renderer, tex) ;
   return result ;
}

Richard.
reading pixels from a TARGET texture
Sanette
Guest

thanks, I will try; this brings some questions:

* do you means that the current GL_RenderReadPixels does not work ?

* the doc says "WARNING: This is a very slow operation, and should not
  be used frequently." Is this still the case with your version ?

* Ideally I'd rather use an "official" method. Will these changes be
  included in the official SDL2 ?

S.


Le 05/08/2016 à 12:25, ancientcc a écrit :
Quote:
As far as I know, you need to change RenderReadPixels method of > SDL_Renderer. Below is my modified version. > ---------------------------------------------------------------------------- > ------ > OpenGL(function GL_RenderReadPixels): > > http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
reading pixels from a TARGET texture
Sanette
Guest

Le 05/08/2016 à 13:41, rtrussell a écrit :
Quote:
To work around the first issue, and to ameliorate the second, I use this slightly more complex method (when the rectangle you want to read is no larger than the window): > > > > > > > > > Code: > int RenderReadPixels (SDL_Renderer* renderer, const SDL_Rect* rect, >                           Uint32 format, void* pixels, int pitch) > { >    int result ; >    SDL_Rect dst = {0, 0, rect->w, rect->h} ; >    SDL_Texture *tex = SDL_GetRenderTarget (renderer) ; >    SDL_SetRenderTarget (renderer, NULL) ; >    SDL_RenderCopy (renderer, tex, rect, &dst) ; >    result = SDL_RenderReadPixels (renderer, &dst, format, pixels, pitch) ; >    SDL_SetRenderTarget (renderer, tex) ; >    return result ; > } > > Richard.


this seems to be a nice trick for textures that fit the window. Thanks.
reading pixels from a TARGET texture
ancientli


Joined: 01 Jul 2015
Posts: 45
* do you means that the current GL_RenderReadPixels does not work ?
------------------
Yes, If you want to read pixels from SDL_TEXTUREACCESS_TARGET's SDL_texture, current GL_RenderReadPixels will work unsuccessfully. Of course, GL_RenderReadPixels is corresponding to Open GL, for example Microsoft Windows with SDL_WINDOW_OPENGL. If your app use OpenGL ES2, for example iOS and Android, you require modify GLES2_RenderReadPixels. Their modification are the same.

* the doc says "WARNING: This is a very slow operation, and should not
be used frequently." Is this still the case with your version ?
------------------
This still the case with my version, modify don't touch that. You should absolutely not use SDL_RenderReadPixels(), ever, for anything other than screenshots and the like.

* Ideally I'd rather use an "official" method. Will these changes be
included in the official SDL2 ?
------------------
I think that next official SDL2 will fix this BUG. Of course, I hope to patch code to official SDL2, especial BLE.


If you want read pixels from tex(it's type must be SDL_TEXTUREACCESS_TARGET), you can write below code.
int RenderReadPixels (SDL_Renderer* renderer, const SDL_Rect* rect,
Uint32 format, void* pixels, int pitch, SDL_Texture* tex)
{
// assume current target is NULL.
int result ;
SDL_Rect dst = {0, 0, rect->w, rect->h} ;
// Since want to read from tex, should set it to target.
SDL_SetRenderTarget(renderer, tex) ;
// pitch = dst.w * byte of one pixel. not tex'width * byte of pixel.
result = SDL_RenderReadPixels(renderer, &dst, format, pixels, pitch);

// recover target to NULL.
SDL_SetRenderTarget (renderer, NULL) ;
return result ;
}
<DKIM> Re: reading pixels from a TARGET texture
Sanette
Guest

Le 05/08/2016 à 14:57, Sanette a écrit :
Quote:


this seems to be a nice trick for textures that fit the window. Thanks.

I've just tested this, indeed it fixes the upside-down problem, and it's
even slightly faster
(I get 350 FPS instead of 300 FPS for my test)

thx again
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org