Creating some effects by editing pixels

Hello everyone.
I’m currently developping a game, initially coded with SDL 1.2. But lately, I felt the need to translate everything to SDL 2, and that’s what I did.
First, I’d like to congratulate the developpers for this incredible job, it is much more faster than SDL 1.2 and it really makes the game much more fun to play.

But I still have some questions:
In my game there are two worlds, the normal world, and the world of the deads. So of course, when you die, you are teleported into the world of the deads.
To make a difference between those two worlds, I decided that the world of the deads would be the same as the normal world, excepted that it is in black & white (Grayscale).

Until now, with SDL 1.2, in order to realize that effect, I had no choice but to copy every image of the decor twice in the RAM, and to modify them at the loading of the game, in order to draw them on screen when you’re dead, without doing any operations.
It’s not the best solution in my opinion, because it uses more ram, and it’s very static, I can’t add more effects, etc.
But I had already try operating every pixels of the screen each frame before refreshing the screen, and my CPU went crazy (It was really slow).

But… here I am with SDL 2, and I was wondering what is the best way to realize those effects ?
I know that It would probably be with shaders, but I prefer not to use them, because I don’t want to use OpenGL, and most of all, shaders can’t be used by everyone, and I want my game to be accessible (even if nowadays it’s pretty rare to have computers that don’t handle shaders).
I would like to know a way to do operations to every pixels of the screen (except for some images like HUD and stuff) each frame, but fasterer than before.
Because it is much more convinient than the other way, insofar as I can do more than one effect (grayscale for example), and I can animate the effect. Because currently, when you die, the decor becomes instantly gray. It would be nicer if it turned gray slowly, and with the current way to realize this effect, it’s not possible.
Moreover, I’d like to realise others effects in the same style. For instance, my game has a day/night system, and actually, it’s just a filter blended with alpha that does the effect. But it’s not beautiful, it would be really nice if the color could change during night, instead of being only darker.

I don’t know if you understood my point or what I’m trying to do, but I’d really appreciate if you could help me and show me a good way to do this: without using OpenGL, and a way faster enough not to turn my CPU crazy :slight_smile:

I thank everyone in advance !
Grade.

Try
SDL_SetTextureColorMod(SDL_Texture* texture,
Uint8 r,
Uint8 g,
Uint8 b);

To colorize a texture. Try RGB (100, 100, 100) to darken a texture and make
it seem gray. Try RGB (80, 80, 140) to make it seem like night time (Dark
Blue tint).

Play with the values of r, g, and b to get the results you want. If you
want to adjust alpha too, there is a separate function for that.

Pallav Nawani
IronCode Gaming Private Limited
Website: http://www.ironcode.com
Twitter: http://twitter.com/Ironcode_Gaming
Facebook: http://www.facebook.com/Ironcode.Gaming
Mobile: 9997478768On Sat, Jul 12, 2014 at 6:57 PM, Grade wrote:

Hello everyone.
I’m currently developping a game, initially coded with SDL 1.2. But
lately, I felt the need to translate everything to SDL 2, and that’s what I
did.
First, I’d like to congratulate the developpers for this incredible job,
it is much more faster than SDL 1.2 and it really makes the game much more
fun to play.

But I still have some questions:
In my game there are two worlds, the normal world, and the world of the
deads. So of course, when you die, you are teleported into the world of the
deads.
To make a difference between those two worlds, I decided that the world of
the deads would be the same as the normal world, excepted that it is in
black & white (Grayscale).

Until now, with SDL 1.2, in order to realize that effect, I had no choice
but to copy every image of the decor twice in the RAM, and to modify them
at the loading of the game, in order to draw them on screen when you’re
dead, without doing any operations.
It’s not the best solution in my opinion, because it uses more ram, and
it’s very static, I can’t add more effects, etc.
But I had already try operating every pixels of the screen each frame
before refreshing the screen, and my CPU went crazy (It was really slow).

But… here I am with SDL 2, and I was wondering what is the best way to
realize those effects ?
I know that It would probably be with shaders, but I prefer not to use
them, because I don’t want to use OpenGL, and most of all, shaders can’t be
used by everyone, and I want my game to be accessible (even if nowadays
it’s pretty rare to have computers that don’t handle shaders).
I would like to know a way to do operations to every pixels of the screen
(except for some images like HUD and stuff) each frame, but fasterer than
before.
Because it is much more convinient than the other way, insofar as I can do
more than one effect (grayscale for example), and I can animate the effect.
Because currently, when you die, the decor becomes instantly gray. It would
be nicer if it turned gray slowly, and with the current way to realize this
effect, it’s not possible.
Moreover, I’d like to realise others effects in the same style. For
instance, my game has a day/night system, and actually, it’s just a filter
blended with alpha that does the effect. But it’s not beautiful, it would
be really nice if the color could change during night, instead of being
only darker.

I don’t know if you understood my point or what I’m trying to do, but I’d
really appreciate if you could help me and show me a good way to do this:
without using OpenGL, and a way faster enough not to turn my CPU crazy [image:
Smile]

I thank everyone in advance !
Grade.


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

Thank you for your response !

I knew this function and it’s very good indeed, and very fast !
However, I just tested with RGB (100, 100, 100), and it just seems to make the texture darker, and it really doesn’t look like the wanted effect. I really want a grayscale effect juste like in a black & white picture.

Is there any other function of this type that can make a texture gray ?

Thank you in advance !
Grade.

You’d need to create a shader that removes the colors while drawing, or
you could also calculate a second B/W texture and draw/mix that in as a
primary/secondary rendering pass.

Here are some general references:
http://www.gamedev.net/page/resources/_/technical/graphics-programming-and-theory/hlsl-greyscale-shader-tutorial-r3263

And SDL specific:
https://hg.libsdl.org/SDL/file/default/test/testshader.c
https://www.opengl.org/wiki/Tutorial2:_VAOs,VBOs,Vertex_and_Fragment_Shaders%28C/_SDL%29On 7/12/2014 8:18 AM, Grade wrote:

Thank you for your response !

I knew this function and it’s very good indeed, and very fast !
However, I just tested with RGB (100, 100, 100), and it just seems to
make the texture darker, and it really doesn’t look like the wanted
effect. I really want a grayscale effect juste like in a black & white
picture.

Is there any other function of this type that can make a texture gray ?

Thank you in advance !
Grade.


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

Isn’t the range [0,255]? That looks like it should make the image less than half as bright as the original. You could try RGB(255, 255, 255).–
Mwlker Narikka

Grade kirjoitti Sat Jul 12 2014 18:18:39 GMT+0300 (EEST):

Thank you for your response !

I knew this function and it’s very good indeed, and very fast !
However, I just tested with RGB (100, 100, 100), and it just seems to make the texture darker, and it really doesn’t look like the wanted effect. I really want a grayscale effect juste like in a black & white picture.

Is there any other function of this type that can make a texture gray ?

Thank you in advance !
Grade.

Oops, never mind, that is a multiplier on the color value.
What you’d want is to sum up the individual color channels and divide those
by three.–
Melker Narikka

On Sat, Jul 12, 2014 at 6:43 PM, <@Melker_Narikka> wrote:

Isn’t the range [0,255]? That looks like it should make the image less
than half as bright as the original. You could try RGB(255, 255, 255).


Mwlker Narikka

Grade kirjoitti Sat Jul 12 2014 18:18:39 GMT+0300 (EEST):

Thank you for your response !

I knew this function and it’s very good indeed, and very fast !
However, I just tested with RGB (100, 100, 100), and it just seems to
make the texture darker, and it really doesn’t look like the wanted effect.
I really want a grayscale effect juste like in a black & white picture.

Is there any other function of this type that can make a texture gray ?

Thank you in advance !
Grade.

The Y = (R+G+B)/3 formula is a quick-n-dirty calculation and will not
always give good results. An even faster calculation is the
approximation Y = (R >> 2) + (G >> 1) + (B >> 2) which is slightly more
accurate. The “photo quality” conversion involves a bit more math.
Wikipedia quotes the formulaY = 0.2126 R + 0.7152 G + 0.0722 B but
people also use Y = 0.299 R + 0.587 G + 0.114 B. Generally one should
apply a gamma correction to convert the resulting Y_linear to Y_sRGB.
This could be done on the CPU with a 256 byte lookup table. The
resulting Y_sRGB value (a byte) can then be used in as the component
values for the RGB pixel, i.e. Uint8 pixel[4] = { Y_sRGB, Y_sRGB,
Y_sRGB, 255 };. When drawing the grayscale texture, it can still be
modulated for brightness and color with SDL_GetTextureColorMod() or
transparency using SDL_GetTextureAlphaMod().

Here is a short SDL2 tutorial with sample images:
http://www.programmersranch.com/2014/02/sdl2-converting-image-to-grayscale.html

Other References:


http://www.fourcc.org/fccyvrgb.php
http://http.developer.nvidia.com/GPUGems3/gpugems3_ch24.htmlOn 7/12/2014 8:45 AM, Melker Narikka wrote:

Oops, never mind, that is a multiplier on the color value.
What you’d want is to sum up the individual color channels and divide
those by three.


Melker Narikka

On Sat, Jul 12, 2014 at 6:43 PM, <meklu at meklu.org <mailto:meklu at meklu.org>> wrote:

Isn't the range [0,255]? That looks like it should make the image
less than half as bright as the original. You could try RGB(255,
255, 255).

--
Mwlker Narikka

Grade kirjoitti Sat Jul 12 2014 18:18:39 GMT+0300 (EEST):
> Thank you for your response !
>
> I knew this function and it's very good indeed, and very fast !
> However, I just tested with RGB (100, 100, 100), and it just
seems to make the texture darker, and it really doesn't look like
the wanted effect. I really want a grayscale effect juste like in
a black & white picture.
>
> Is there any other function of this type that can make a texture
gray ?
>
> Thank you in advance !
> Grade.
>
>
>
>
>

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

2014-07-12 21:27 GMT-03:00, Andreas Schiffler :

Wikipedia quotes the formulaY = 0.2126 R + 0.7152 G + 0.0722 B but
people also use Y = 0.299 R + 0.587 G + 0.114 B.

I just had to deal with this last night when I implemented monochrome
mode in my game, turns out the former is meant to be used with sRGB
(i.e. gamma-corrected) values. If you use linear RGB then you should
consider using the latter instead.

In practice both seem way off (blue looks darker than it should), but
I have no idea what are the correct coefficients. In fact they seem to
vary depending on the person (which probably exacerbates the blue
problem for me, since I don’t see it darker than red, against what
everybody says about the human eye).