Possible bug with copying textures to render targets? How do


#1

Hi,
I suppose you have to use SDL_TEXTUREACCESS_TARGET as access flag in SDL_CreateTexture function.

Code:

SDL_CreateTexture(renderer, fmt, SDL_TEXTUREACCESS_TARGET, w, h);------------------------
I’m SDL newbie


#2

Yeah, I realize. However, this means that the new texture is not an exact
copy.On Fri, Apr 18, 2014 at 7:15 PM, lorin wrote:

Hi,
I suppose you have to use SDL_TEXTUREACCESS_TARGET as access flag in
SDL_CreateTexture function.

Code:

SDL_CreateTexture(renderer, fmt, SDL_TEXTUREACCESS_TARGET, w, h);


I’m SDL newbie


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


#3

I do not think copying of Textures is a good idea at all. They are (as far as I know) stored somewhere on GPU memory. They are designed to fast rendering, but not to access or change.
You always can set access flag SDL_TEXTUREACCESS_STREAMING to texture. In that case pixels data are stored at RAM memory ( AFAIK ) and you can easily edit it by SDL_LockTexture and SDL_UnlockTexture.

On the other hand, I would recomend to create new Texture from SDL_Surface or whatever you load your graphics data from.

PS: I think there is a way how to copy texture.
SDL_QueryTexture - get info about original texture
SDL_CreateTexture - with flag TARGET (call it target texture)
SDL_SetRenderTarget - set it to target texture
SDL_RenderCopy - Render original to target texture
SDL_SetRenderTarget - reset it to default
SDL_RenderReadPixels - Read pixels from target texture
SDL_CreateTexture - Create copy of texture with pixels data from ReadPixels------------------------
I’m SDL newbie


#4

Why read pixels from the target texture in the end?
Also, you can’t give SDL_CreateTexture a pixels pointer. Maybe you mean
SDL_UpdateTexture?
Why do a render copy if later you do an SDL_UpdateTexture?

I had some issues figuring out what “pitch” is and how to get it. Turns out
that you use SDL_LockTexture for that. Also, you get the pixels the same
way.
So no need for renderer hacks with targets and reads. A bit
counter-intiuitive though.

It still doesn’t work though:
Uint32 other_format;
int other_access;
int other_w;
int other_h;
SDL_QueryTexture(other, &other_format, &other_access, &other_w,
&other_h);

SDL_Texture* texture  = SDL_CreateTexture(renderer, other_format,

other_access, other_w, other_h);

int* other_pixels;
int  other_pitch;
SDL_LockTexture(other, nullptr, (void**)&other_pixels, &other_pitch);
int* pixels;
int  pitch;
SDL_LockTexture(texture, nullptr, (void**)&pixels, &pitch);
for (int i = 0; i < pitch * other_h; ++i)
{
    pixels[i] = other_pixels[i];
}
SDL_UnlockTexture(texture);
SDL_UnlockTexture(other);On Sun, Apr 20, 2014 at 7:18 PM, lorin <looorin at gmail.com> wrote:

I do not think copying of Textures is a good idea at all. They are (as
far as I know) stored somewhere on GPU memory. They are designed to fast
rendering, but not to access or change.
You always can set access flag SDL_TEXTUREACCESS_STREAMING to texture. In
that case pixels data are stored at RAM memory ( AFAIK ) and you can easily
edit it by SDL_LockTexture and SDL_UnlockTexture.

On the other hand, I would recomend to create new Texture from SDL_Surface
or whatever you load your graphics data from.

PS: I think there is a way how to copy texture.
SDL_QueryTexture - get info about original texture
SDL_CreateTexture - with flag TARGET (call it target texture)
SDL_SetRenderTarget - set it to target texture
SDL_RenderCopy - Render original to target texture
SDL_SetRenderTarget - reset it to default
SDL_RenderReadPixels - Read pixels from target texture
SDL_CreateTexture - Create copy of texture with pixels data from ReadPixels


I’m SDL newbie


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


#5

I ment something like this (http://pastebin.com/26uhpJW5) by pseudocode posted last time. It is working, however returned texture is 180 degrees rotated. :slight_smile:


#6

Only reason I can see to copy a texture is renderer change.------------------------
Nate Fries


#7

2014-04-20 18:18 GMT+02:00 lorin :

I do not think copying of Textures is a good idea at all. They are (as
far as I know) stored somewhere on GPU memory. They are designed to fast
rendering, but not to access or change.
You always can set access flag SDL_TEXTUREACCESS_STREAMING to texture. In
that case pixels data are stored at RAM memory ( AFAIK ) and you can easily
edit it by SDL_LockTexture and SDL_UnlockTexture.

‘SDL_Lock/UnlockTexture’ is an abstraction of what one would call
"mapping GPU memory into client space"; you’re still (supposedly) writing
directly to
video ram. In the D3D backend, this translates to an actual implementation
call which
I think does this mapping (I don’t know too much about D3D though), whereas
for the
GL backends, this feature is just emulated, ie. SDL gives you a pointer to
a dumb
buffer allocated in RAM, and upon the Unlock call just UpdateTexture’s the
whole
thing back into the native texture object.
This is why you cannot expect the pointer returned by LockTexture to
contain any
data representative of what’s actually in the texture (the documentation
will tell you
the same).

Here’s more on the D3D part (which SDL’s locking is based on):
http://msdn.microsoft.com/en-us/library/windows/desktop/bb205913(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/bb172231(v=vs.85).aspx


#8

I have this same problem, and where-ever it is asked, someone asks “why do you need to copy a texture?”

I have the same issue as many other people: I want to load in an image file (say a png) and then modify it programmatically. I believe it is a bug that the default behavior in CreateTextureFromSurface is to make it non-streaming.

Basically, I need to be able to procedurally modify textures, and I’d like to also be able to use the image library. Can anyone provide a way to load an image into a texture with streaming properties so I can modify it? This notion that you can put every possible graphical function inside SDL is ridiculous - you have to be able to calculate some pixel values yourself.


#9

How can you set this access flag if you didn’t create the texture because you wanted to load an image file?


#10

If there’s not already a bug report for this, maybe you can file one on Bugzilla.

Would it be possible for you to use a SDL_Surface as the definitive image and update a streaming texture as you go? Then you can copy the surface and create associated textures as much as you like.

SDL_gpu does have a bit more flexibility in this regard. You might find what you want in there. I use textures for a pixel editor which uses SDL_gpu. If I’m going to duplicate a frame or layer and most editing is done via shaders, it makes sense to copy the texture.


#11

Thanks for the tip. As we speak, I’m looking into using SDL_Surfaces directly for much of this stuff - of course, it has overhead. But I’ll check out SDL_gpu. :slight_smile: