Change TEXTURE_ACCESS from TARGET to STREAMING

Hey,
I need to change the TEXTURE_ACCESS of some textures from TARGET to STREAMING, because i want to access and change individual pixels. My best guess was to use SDL_RenderReadPixels of my TARGET-texture and write the pixel data into a new STREAMING-texture, but the resulting STREAMING-texture is flipped upside-down and i don’t really know why that happens (maybe because open_gl has it’s origin in the bottom-left and not top-left?) and how to fix it…
My code looks like this:

Code:

SDL_Texture* targetTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, width, height);
SDL_SetRenderTarget(renderer, targetTexture);
//render some things onto targetTexture
SDL_Texture* streamingTexture = SDL_CreateTexture( renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, width, height );
void* streamingPixels;
int streamingPitch;
SDL_LockTexture( streamingTexture, NULL, &streamingPixels, &streamingPitch );
SDL_RenderReadPixels(renderer, NULL, SDL_PIXELFORMAT_RGBA8888, streamingPixels, streamingPitch);
SDL_UnlockTexture( streamingTexture );
SDL_SetRenderTarget(renderer, NULL);

Any help is appreciated :slight_smile:

stewambo wrote:

Any help is appreciated

This bug (https://bugzilla.libsdl.org/show_bug.cgi?id=2740) maybe? If it is, this is the workaround I use (it won’t be a drop-in replacement for your code because it assumes a non-NULL rect):

Code:
// Bugfix version of SDL_RenderReadPixels (SDL Bugzilla 2740)
// Also much faster on some platforms because reading pixels from the
// default render target is faster than reading from a target texture.
// n.b. This bugfix routine cannot read a bigger rect than the window!
int Fix_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.

Yes, that’s the bug I’m having and your “solution” worked, however I don’t really like it, because it just draws the texture I want to convert onto my main renderer and IF I would call it every frame I would see this texture in the top left corner of my window. Of course I wouldn’t call it every frame, but in my case only every couple of seconds or even minutes, depending on whats happening in game, but it still bugs me that i would be able to see a texture that has nothing to do there…

Would it be easier to to the pixel manipulation on a surface instead of a streaming texture? Would it even be possible to create a surface from a texture without the use of SDL_RenderReadPixels? And what has better performance? Using a streaming texture or changing the pixels on a surface and then creating a texture out of it?

Can a negative pitch/stride be used to flip the buffer?On 9 October 2016 at 16:02, stewambo wrote:

Yes, that’s the bug I’m having and your “solution” worked, however I don’t
really like it, because it just draws the texture I want to convert onto my
main renderer and IF I would call it every frame I would see this texture
in the top left corner of my window. Of course I wouldn’t call it every
frame, but in my case only every couple of seconds or even minutes,
depending on whats happening in game, but it still bugs me that i would be
able to see a texture that has nothing to do there…

Would it be easier to to the pixel manipulation on a surface instead of a
streaming texture? Would it even be possible to create a surface from a
texture without the use of SDL_RenderReadPixels? And what has better
performance? Using a streaming texture or changing the pixels on a surface
and then creating a texture out of it?


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

SDL_RenderReadPixels(renderer, NULL, SDL_PIXELFORMAT_RGBA8888,
streamingPixels, streamingPitch * -1);On 9 October 2016 at 16:30, Travis McKinney <@Travis_McKinney> wrote:

Can a negative pitch/stride be used to flip the buffer?

On 9 October 2016 at 16:02, stewambo wrote:

Yes, that’s the bug I’m having and your “solution” worked, however I
don’t really like it, because it just draws the texture I want to convert
onto my main renderer and IF I would call it every frame I would see this
texture in the top left corner of my window. Of course I wouldn’t call it
every frame, but in my case only every couple of seconds or even minutes,
depending on whats happening in game, but it still bugs me that i would be
able to see a texture that has nothing to do there…

Would it be easier to to the pixel manipulation on a surface instead of a
streaming texture? Would it even be possible to create a surface from a
texture without the use of SDL_RenderReadPixels? And what has better
performance? Using a streaming texture or changing the pixels on a surface
and then creating a texture out of it?


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

No, immediately crashes with a “Access violation writing location …”

https://wiki.libsdl.org/SDL_RenderCopyEx
" Use this function to copy a portion of the texture to the current
rendering target, optionally rotating it by angle around the given center
and also flipping it top-bottom and/or left-right. "On 9 October 2016 at 16:42, stewambo wrote:

No, immediately crashes with a “Access violation writing location …”


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Can you try the latest SDL snapshot? I think this is fixed:
http://www.libsdl.org/tmp/SDL-2.0.zipOn Sun, Oct 9, 2016 at 12:54 PM, stewambo wrote:

Hey,
I need to change the TEXTURE_ACCESS of some textures from TARGET to
STREAMING, because i want to access and change individual pixels. My best
guess was to use SDL_RenderReadPixels of my TARGET-texture and write the
pixel data into a new STREAMING-texture, but the resulting
STREAMING-texture is flipped upside-down and i don’t really know why that
happens (maybe because open_gl has it’s origin in the bottom-left and not
top-left?) and how to fix it…
My code looks like this:

Code:

SDL_Texture* targetTexture = SDL_CreateTexture(renderer,
SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, width, height);
SDL_SetRenderTarget(renderer, targetTexture);
//render some things onto targetTexture
SDL_Texture* streamingTexture = SDL_CreateTexture( renderer,
SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, width, height );
void* streamingPixels;
int streamingPitch;
SDL_LockTexture( streamingTexture, NULL, &streamingPixels, &streamingPitch
);
SDL_RenderReadPixels(renderer, NULL, SDL_PIXELFORMAT_RGBA8888,
streamingPixels, streamingPitch);
SDL_UnlockTexture( streamingTexture );
SDL_SetRenderTarget(renderer, NULL);

Any help is appreciated [image: Smile]


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Travis McKinney wrote:

it still bugs me that i would be able to see a texture that has nothing to do there…

Can’t you clear it before your SDL_RenderPresent, for example with SDL_RenderClear? In my application it’s not an issue because the entire window is rendered every frame so any ‘temporary’ textures get overwritten anyway. It’s an ideal solution for me because it doesn’t depend on the bug being present (it will work either way) and it’s typically faster than SDL_RenderReadPixels anyway, so it’s a win-win situation.

Richard.

https://wiki.libsdl.org/SDL_RenderCopyEx
" Use this function to copy a portion of the texture to the current rendering target, optionally rotating it by angle around the given center and also flipping it top-bottom and/or left-right. "

Yeah, I could just flip the texture right before I call SDL_RenderReadPixels, but in another thread I read that this bug only happens sometimes, so not on all platforms/renderers. So I would need to check on startup if this bug is present and remember it. I’ll keep this solution in my mind.

Can you try the latest SDL snapshot? I think this is fixed:http://www.libsdl.org/tmp/SDL-2.0.zip

I just downloaded your zip file, compiled the SDL and SDLmain (from VisualC folder) in Visual studio, replaced my current includes, .dll and .lib files with the newly created ones, rebuilt my own application and the bug still persists.

Can’t you clear it before your SDL_RenderPresent, for example with SDL_RenderClear?

Not if I need to convert a texture during my render calls because then I would clear all objects that have already been renderered. Of course if I converted my textures before my render calls it would work, but sometimes I create new target textures to draw on during my render calls, which I immediately need to convert to do some pixel manipulation…