How to Grayscale Texture

Would like to use SDL_Texture widely in code, but SDL_RenderReadPixel is too
low, require grayscale texture directly. How to do?

By the way, I use below code to grayscale SDL_Surface.

// beg is begin pixel of SDL_Surface.

// end is end pixel of SDL_Surface + 1.

while (beg != end) {

          Uint8 alpha = (*beg) >> 24;

          if (alpha) {

                       Uint8 r, g, b;

                       r = (*beg) >> 16;

                       g = (*beg) >> 8;

                       b = (*beg);

                       // const Uint8 avg = (red+green+blue)/3;

                        // gray=0.299red+0.587green+0.114blue

                       const Uint8 avg = static_cast<Uint8>((

                                     77  * static_cast<Uint16>(r) +

                                     150 * static_cast<Uint16>(g) +

                                     29  * static_cast<Uint16>(b)  ) /

256);

                       *beg = (alpha << 24) | (avg << 16) | (avg << 8) |

avg;

          }

          ++beg;

}

[…]

Is this something that needs to be done in real time, or can you
preprocess the graphics at load time?

If it needs to be real time, you should use procedural textures, using
an SDL_Surface or a raw buffer as source data. (See
SDL_TEXTUREACCESS_STREAMING.)

You should absolutely not use SDL_RenderReadPixels(), ever, for
anything other than screenshots and the like. It’s typically faster to
do all rendering in software, just to avoid ever moving data from VRAM
to system memory. :slight_smile:

If you want it all really fast and accelerated, you probably need to
use custom shaders, but AFAIK, that’s not directly supported by the
SDL 2D API, so you’d have to move to OpenGL or Direct3D.On Tue, Jul 26, 2016 at 1:10 PM, ancientcc wrote:

Would like to use SDL_Texture widely in code, but SDL_RenderReadPixel is too
low, require grayscale texture directly. How to do?

//David Olofson - Consultant, Developer, Artist, Open Source Advocate

.— Games, examples, libraries, scripting, sound, music, graphics —.
| http://consulting.olofson.net http://olofsonarcade.com |
’---------------------------------------------------------------------’

Here’s a good tutorial I found a while ago: http://gigi.nullneuron.net/gigilabs/converting-an-image-to-grayscale-using-sdl2/

I give an example of use: 1)Generate tow texture from tow *.png file, 2)Use
SDL_RenderCopy, generate new texture base on these tow texture. 3)Need
grayscale the new texture.

I have a question, to above case, even use SDL_TEXTUREACCESS_STREAMING, it
require move pixels data from VRAM to system memory. In order to move, is
there method except SDL_RenderReadPixels?> ----- Original Message -----

Is this something that needs to be done in real time, or can you preprocess
the graphics at load time?

If it needs to be real time, you should use procedural textures, using an
SDL_Surface or a raw buffer as source data. (See
SDL_TEXTUREACCESS_STREAMING.)

You should absolutely not use SDL_RenderReadPixels(), ever, for anything
other than screenshots and the like. It’s typically faster to do all
rendering in software, just to avoid ever moving data from VRAM to system
memory. :slight_smile:

If you want it all really fast and accelerated, you probably need to use
custom shaders, but AFAIK, that’s not directly supported by the SDL 2D API,
so you’d have to move to OpenGL or Direct3D.


//David Olofson - Consultant, Developer, Artist, Open Source Advocate

.— Games, examples, libraries, scripting, sound, music, graphics —.
| http://consulting.olofson.net http://olofsonarcade.com |
’---------------------------------------------------------------------’


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

It’s that move from GPU to RAM that is costly, not the function.

SDL_gpu has a shader interface that would make this a snap.

Jonny DOn Tue, Jul 26, 2016 at 10:55 AM, ancientcc wrote:

I give an example of use: 1)Generate tow texture from tow *.png file, 2)Use
SDL_RenderCopy, generate new texture base on these tow texture. 3)Need
grayscale the new texture.

I have a question, to above case, even use SDL_TEXTUREACCESS_STREAMING, it
require move pixels data from VRAM to system memory. In order to move, is
there method except SDL_RenderReadPixels?

-----Original Message-----
Is this something that needs to be done in real time, or can you preprocess
the graphics at load time?

If it needs to be real time, you should use procedural textures, using an
SDL_Surface or a raw buffer as source data. (See
SDL_TEXTUREACCESS_STREAMING.)

You should absolutely not use SDL_RenderReadPixels(), ever, for anything
other than screenshots and the like. It’s typically faster to do all
rendering in software, just to avoid ever moving data from VRAM to system
memory. :slight_smile:

If you want it all really fast and accelerated, you probably need to use
custom shaders, but AFAIK, that’s not directly supported by the SDL 2D API,
so you’d have to move to OpenGL or Direct3D.


//David Olofson - Consultant, Developer, Artist, Open Source Advocate

.— Games, examples, libraries, scripting, sound, music, graphics —.
| http://consulting.olofson.net http://olofsonarcade.com |
’---------------------------------------------------------------------’


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