Get pixel RGB values from a texture

Hi all,

In SDL2, there’s a way to get the RGB values of a pixel that are in a
loaded texture ?

In SDL 1.2 I use the “SDL_Color get_pixel32” routine to get this
values from a Surface.–
Thanks

1 Like

Nope, textures are write-only, with the exception of render targets, which
you can read back with the slow SDL_RenderReadPixels() function.On Tue, Aug 27, 2013 at 2:53 PM, David Lara wrote:

Hi all,

In SDL2, there’s a way to get the RGB values of a pixel that are in a
loaded texture ?

In SDL 1.2 I use the “SDL_Color get_pixel32” routine to get this
values from a Surface.


Thanks


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

1 Like

Sam Lantinga wrote:

Nope, textures are write-only, with the exception of render targets, which you can read back with the slow SDL_RenderReadPixels() function.

Hi all,

In SDL2, there’s a way to get the RGB values of a pixel that are in a
loaded texture ?

In SDL 1.2 I use the “SDL_Color get_pixel32” routine to get this
values from a Surface.


Thanks


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

Also, streaming textures, which are useful for things like dynamically generated minimaps.
However, I’m not sure why you’d want to read pixels from a texture unless you were doing graphics processing. If you are, it would be better to use surfaces than textures.
That, or you’re trying to rig a system so that the user can change the renderer at runtime. A good idea, but since you have to maintain a list of textures to do this anyway, you might as well identify where each texture was loaded from in that list.> On Tue, Aug 27, 2013 at 2:53 PM, David Lara <dvlara at gmail.com (dvlara at gmail.com)> wrote:


Nate Fries

1 Like

I’m not sure why you’d want to read pixels from a texture unless you
were doing graphics processing.


I’m trying to do a pixel-collision (The game has a lot of irregular
objects). I’m trying to do “Check if the RGB of this pixel is 255” or
"Check alpha value of this pixel".

1 Like

I’m trying to do a pixel-collision (The game has a lot of irregular
objects). I’m trying to do “Check if the RGB of this pixel is 255” or
"Check alpha value of this pixel".

If you’re only interested whether a pixel is 100% transparent, it
might be more efficient to keep a separate bitmap around for each
object (where each pixel can be represented by a single bit).

Other than that, streaming textures work fine, but you are basically
keeping a complete copy of the pixel data in memory. Use
SDL_LockTexture to access that pixel data at a later point. That’s
what I do, so that I can compose images off-screen.

Render Targets might work, but from my own experience they are much
slower than streaming textures.

KaiOn Thu, Aug 29, 2013 at 7:29 AM, David Lara wrote:

1 Like

dvlara wrote:


I’m not sure why you’d want to read pixels from a texture unless you
were doing graphics processing.


I’m trying to do a pixel-collision (The game has a lot of irregular
objects). I’m trying to do “Check if the RGB of this pixel is 255” or
"Check alpha value of this pixel".


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

You wouldn’t want to download from GPU memory each time you wanted to do collision detection anyway. Your code would be so slow as to basically render it useless, and there’d be little you can do about it.
What you want to do is hold a separate collision copy. Not only does this prevent having to constantly download from the GPU, but it allows for useful things like compression by eliminating color data or using an 8-bit palette to enable different types of collisions.

However, you might still find that pixel-perfect collision is slow, especially if non-player entities can collide with other non-player entities (the case with most great games). A rectangle or quadtree approach should yield better performance, even if a little accuracy is lost.------------------------
Nate Fries

1 Like

I realize this is an old post but I had to try per pixel collision myself, I did some experiments and I have some follow up information.

…the slow SDL_RenderReadPixels()

“Slow” is definitely accurate, I would add “prohibitively slow for any 60 FPS game”

  • From my testing it appears to take around 15 ms to run this function on even a tiny 32x32 pixel RGBA texture on my GTX 1070.
  • This operation alone would immediately destroy your chances of running a 60 FPS game.

Probably because…

You wouldn’t want to download from GPU memory each time you wanted to do collision detection anyway. Your code would be so slow as to basically render it useless, and there’d be little you can do about it.

I didn’t know this going into it but it looks like Textures are stored completely on the GPU. It makes sense that there would be some latency when memory is transferred from the GPU to the CPU.

Another reason why I thought at first I would be better off doing pixel based collision is because I will have a lot of bounding boxes, but even at very low res it’s still not viable.

Other than that, streaming textures work fine, but you are basically
keeping a complete copy of the pixel data in memory.

This sounded promising at first but there does not seem to be an easy way to transfer pixel data from a render target texture to a streaming texture.

I have an image processing background and I was originally thinking that I could use blend modes (e.g., MOD) to find where pixels of one sprite intersected another. This doesn’t really seem practical at all.

There’s two things that I tried,

  1. Blend using render target textures, then use SDL_RenderReadPixels() and iterate over every pixel for non-transparent ones. This was no good because SDL_RenderReadPixels() is too slow, and there is no function like “return true if any pixel is non-transparent” that works on the texture itself.
  2. From the sound of it, it would be faster to iterate over every pixel of a streaming texture, but the problem is I think I would have to do all the blending by hand.

Considering that option 1 is slow, and option 2 is no better than doing my own bounding box code anyway, I think I will give up on this whole “pixel based collision” idea.

In any case, if anyone’s curious, here is my ill fated collision code (should be easy to get working in Windows, but it only has a Makefile).

Unfortunately it looks like I can’t edit my post, I didn’t anticipate that.

Sorry for the double post but I think this is pretty important because I found that the whole pixel based collision thing probably isn’t necessary and I wanted to show an alternative.

I was quite impressed by the performance of SDL_HasIntersection.

  • From my experiments even on a very weak PC (AMD Athlon II X2 220 / Radeon HD 4200) checking collision with 8000 bounding boxes takes a negligible amount of time.

  • On my main rig, I have to do 200k collision checks before it takes even 1 ms to test collision with all of them.

  • I’m pretty sure I could have more bounding boxes than pixels on the screen for this low res game before it would make a difference, which is good enough for me.

  • For higher resolution games maybe you would start having a performance problem if you had something like 1 million bounding boxes, but I can’t think of a situation where that would be practical (how would a player see a 2x2 pixel player sprite and navigate it through such a complicated collision map?)

This is a rather verbose way of saying “even if your game has thousands of bounding boxes, it’s still less overhead to do thousands of rectangle checks instead of re-using rendered pixels”. Yet another case where rendering is still the bottleneck.

Hope that helps somebody

1 Like