Getting at a Texture's Pixels

A search of the archives showed someone asked this question a while
ago, but it was never answered. How does one go about getting the
pixels from a texture now that SDL_QueryTexturePixels has been
removed?

I have a D binding to SDL 2 and someone recently asked me to expose
the SDL_Texture struct as defined in sysrender.h. Of course, I’m not
about to do that. Apparently, in C, he’s bypassing the public API and
accessing the struct field directly. But this has got me curious.

I don’t trust the wiki anymore as being up-to-date, but skimming
through the headers nothing stands out at me as a way to get at a
texture’s pixels. Am I missing something?–
Mike Parker

SDL_LockTexture lets you access the pixels of a texture directly. The
third and fourth parameters are what you’re looking for. To give you
an idea, this is what my game is doing when it updates the texture
used to show the graphics:

void *dest; int pitch;
if (SDL_LockTexture(texture, NULL, &dest, &pitch))
abort_program(ERR_UPDATEVIDEO, NULL);
const uint32_t *src = framebuffer;
for (int y = 0; y < screen_h; y++) {
memcpy(dest, src, sizeof(uint32_t) * screen_w);
src += screen_w;
dest += pitch;
}
SDL_UnlockTexture(texture);

Of course this is writing but I imagine it isn’t much different for
reading (and before you ask about memcpy, I explicitly make sure the
texture is made to match the source data :P).

2013/4/11, Michael Parker :> A search of the archives showed someone asked this question a while

ago, but it was never answered. How does one go about getting the
pixels from a texture now that SDL_QueryTexturePixels has been
removed?

I have a D binding to SDL 2 and someone recently asked me to expose
the SDL_Texture struct as defined in sysrender.h. Of course, I’m not
about to do that. Apparently, in C, he’s bypassing the public API and
accessing the struct field directly. But this has got me curious.

I don’t trust the wiki anymore as being up-to-date, but skimming
through the headers nothing stands out at me as a way to get at a
texture’s pixels. Am I missing something?


Mike Parker


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

I can confirm that this also works for writing. However, I believe that the
texture must be created with SDL_TEXTUREACCESS_STREAMING access mode.
Otherwise it is not lockable.

Regards,

KaiOn Thu, Apr 11, 2013 at 10:45 AM, Sik the hedgehog < sik.the.hedgehog at gmail.com> wrote:

SDL_LockTexture lets you access the pixels of a texture directly. The
third and fourth parameters are what you’re looking for. To give you
an idea, this is what my game is doing when it updates the texture
used to show the graphics:

void *dest; int pitch;
if (SDL_LockTexture(texture, NULL, &dest, &pitch))
abort_program(ERR_UPDATEVIDEO, NULL);
const uint32_t *src = framebuffer;
for (int y = 0; y < screen_h; y++) {
memcpy(dest, src, sizeof(uint32_t) * screen_w);
src += screen_w;
dest += pitch;
}
SDL_UnlockTexture(texture);

Of course this is writing but I imagine it isn’t much different for
reading (and before you ask about memcpy, I explicitly make sure the
texture is made to match the source data :P).

2013/4/11, Michael Parker :

A search of the archives showed someone asked this question a while
ago, but it was never answered. How does one go about getting the
pixels from a texture now that SDL_QueryTexturePixels has been
removed?

I have a D binding to SDL 2 and someone recently asked me to expose
the SDL_Texture struct as defined in sysrender.h. Of course, I’m not
about to do that. Apparently, in C, he’s bypassing the public API and
accessing the struct field directly. But this has got me curious.

I don’t trust the wiki anymore as being up-to-date, but skimming
through the headers nothing stands out at me as a way to get at a
texture’s pixels. Am I missing something?


Mike Parker


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


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

Thanks, guys. I was sure I had overlooked something.On Thu, Apr 11, 2013 at 6:21 PM, Kai Sterker <kai.sterker at gmail.com> wrote:

I can confirm that this also works for writing. However, I believe that the
texture must be created with SDL_TEXTUREACCESS_STREAMING access mode.
Otherwise it is not lockable.

Regards,

Kai

On Thu, Apr 11, 2013 at 10:45 AM, Sik the hedgehog <sik.the.hedgehog at gmail.com> wrote:

SDL_LockTexture lets you access the pixels of a texture directly. The
third and fourth parameters are what you’re looking for. To give you
an idea, this is what my game is doing when it updates the texture
used to show the graphics:

void *dest; int pitch;
if (SDL_LockTexture(texture, NULL, &dest, &pitch))
abort_program(ERR_UPDATEVIDEO, NULL);
const uint32_t *src = framebuffer;
for (int y = 0; y < screen_h; y++) {
memcpy(dest, src, sizeof(uint32_t) * screen_w);
src += screen_w;
dest += pitch;
}
SDL_UnlockTexture(texture);

Of course this is writing but I imagine it isn’t much different for
reading (and before you ask about memcpy, I explicitly make sure the
texture is made to match the source data :P).

2013/4/11, Michael Parker <@Michael_Parker>:

A search of the archives showed someone asked this question a while
ago, but it was never answered. How does one go about getting the
pixels from a texture now that SDL_QueryTexturePixels has been
removed?

I have a D binding to SDL 2 and someone recently asked me to expose
the SDL_Texture struct as defined in sysrender.h. Of course, I’m not
about to do that. Apparently, in C, he’s bypassing the public API and
accessing the struct field directly. But this has got me curious.

I don’t trust the wiki anymore as being up-to-date, but skimming
through the headers nothing stands out at me as a way to get at a
texture’s pixels. Am I missing something?


Mike Parker


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


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


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


Mike Parker

I think using SDL_LockTexture might not be best solution.

What I don’t like in it, is that it’s marked as a write-only function in
its documentation, and it doesn’t work for every texture. The second thing
is that it involves a lot of copy, and it’s slow, maybe too slow.

An alternative for it, which works really awesome in c++, but sadly not
that good in c, is to store an SDL_Surface copy of the image too. Basically
in c++ you can make your own image class that can be edited like an
SDL_Surface and is copied as fast as a texture. Also you can copy pictures
to each other just by using opeator=(), however without storing surfaces
you couldn’t blit textures to each other. And the best in it, is that the
surface part can stay locked, you can access its pixels like it was 2d
array, without any slowdown caused by locking, at still be able to render
the texture to the screen with full speed. Basically you can use this class
everywhere where you can use SDL_Texture* or SDL_Surface* if you make the
appropriate cast operators, but you can also handle a lot of exception
pretty easily, which makes debugging thousand times easier, and you can’t
do with the SDL’s built in structs. And of course you can make constructor
to be able to create only the SDL_Texture part in your image class, if
don’t need the extra features or is in lack of memory.

In c, well, the basic idea still works, you can still have a struct that
contains a surface and a texture, and you can write functions for it, but
it won’t be as convenient to use it.On Apr 11, 2013 10:06 AM, “Michael Parker” wrote:

A search of the archives showed someone asked this question a while
ago, but it was never answered. How does one go about getting the
pixels from a texture now that SDL_QueryTexturePixels has been
removed?

I have a D binding to SDL 2 and someone recently asked me to expose
the SDL_Texture struct as defined in sysrender.h. Of course, I’m not
about to do that. Apparently, in C, he’s bypassing the public API and
accessing the struct field directly. But this has got me curious.

I don’t trust the wiki anymore as being up-to-date, but skimming
through the headers nothing stands out at me as a way to get at a
texture’s pixels. Am I missing something?


Mike Parker


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

I think using SDL_LockTexture might not be best solution.

What I don’t like in it, is that it’s marked as a write-only function in its documentation, and it doesn’t work for every texture. The second thing is that it involves a lot of copy, and it’s slow, maybe too slow.

I haven’t checked SDL code lately, but when I did my implementation,
streaming textures already kept a copy of the pixel data that was made
accessible on lock and written back to the texture on unlock. It even
allows locking of specific areas only, in case one doesn’t have to
update the whole texture.

With that in mind, I wrote a little method that would wrap that pixel
data inside an SDL_Surface in order to allow blitting from one surface
to another. Code is here:

You can see it in action here

I’ve also experimented with render targets (using the aforementioned
SDL_RenderReadPixels, but performance was much slower than the above.

Not sure how well it compares to your implementation, which should be
similar in principle. Note that there seems to be no need to unlock
the texture again, unless you made changes to the pixel data and want
the underlying texture to receive an update.

Also note that I only ever tried this with the OpenGL renderer so far,
but I would expect that it works the same with the other renderers as
well.

KaiOn Thu, Apr 11, 2013 at 5:31 PM, Csala Tam?s wrote: