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
Change TEXTURE_ACCESS from TARGET to STREAMING
stewambo


Joined: 04 Jun 2016
Posts: 13
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 Smile
Re: Change TEXTURE_ACCESS from TARGET to STREAMING
rtrussell


Joined: 10 Feb 2016
Posts: 88
stewambo wrote:
Any help is appreciated

This bug 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.
stewambo


Joined: 04 Jun 2016
Posts: 13
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?
Change TEXTURE_ACCESS from TARGET to STREAMING
Travis McKinney
Guest

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


On 9 October 2016 at 16:02, stewambo wrote:
Quote:
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

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

Change TEXTURE_ACCESS from TARGET to STREAMING
Travis McKinney
Guest

SDL_RenderReadPixels(renderer, NULL, SDL_PIXELFORMAT_RGBA8888, streamingPixels, streamingPitch * -1);

On 9 October 2016 at 16:30, Travis McKinney wrote:
Quote:
Can a negative pitch/stride be used to flip the buffer?


On 9 October 2016 at 16:02, stewambo wrote:
Quote:
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

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




stewambo


Joined: 04 Jun 2016
Posts: 13
No, immediately crashes with a "Access violation writing location ..."
Change TEXTURE_ACCESS from TARGET to STREAMING
Travis McKinney
Guest

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:
Quote:
No, immediately crashes with a "Access violation writing location ..."


_______________________________________________
SDL mailing list

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

Change TEXTURE_ACCESS from TARGET to STREAMING
Sam Lantinga


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




On Sun, Oct 9, 2016 at 12:54 PM, stewambo wrote:
Quote:
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


_______________________________________________
SDL mailing list

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

Re: Change TEXTURE_ACCESS from TARGET to STREAMING
rtrussell


Joined: 10 Feb 2016
Posts: 88
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.
stewambo


Joined: 04 Jun 2016
Posts: 13
Quote:
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.

Quote:
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.

Quote:
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...