Per-pixel alpha transparency in loaded texture?

So this is my issue: I’m trying to implement a day/night cycle for my video game, but I’m an amateur at this and I’m having some issues. This is what I’ve tried:

At first I simply made a completely black texture that covered the entire screen. I change its alpha transparency as a function of time using SDL_SetTextureAlphaMod. This works fine.
Then, to give me more control over which parts of the screen goes dark at night (to be able to implement light sources and such) I split the screen into blocks of 16x16 pixels. The problem with this is that this ends up being around 3000 extra textures I need to apply for every frame render, which in turn is a significant performance loss!

I then thought perhaps it would be faster to just do this by rendering geometry instead. I followed the tutorial at:
http://lazyfoo.net/tutorials/SDL/08_geometry_rendering/index.php
The problem with this is that even though I can specify an alpha transparency when I use SDL_RendererDrawColor it seems the value is being ignored. I then figured that instead of using a block-based alpha transparency, why not just have my initial black texture covering the entire screen then changing the alpha transparency on a per-pixel basis using texture manipulation. That way I won’t have to constantly reload more than one texture and I don’t get an ugly block-based looking light-sources. I follow the tutorial on texture manipulation here:
http://lazyfoo.net/tutorials/SDL/40_texture_manipulation/40_texture_manipulation.zip (which for the moment is just a piece of code, but it’s pretty self explanatory) but I cannot figure out how to make the transparency work.
I can change an area of pixels from any color to a different color but i cannot give them alpha transparency. What am I missing? I would post code but the code is pretty much exactly as in the texture manipulation tutorial, only that I’m attempting to make the cyan background colour of the guy more transparent instead of changing its color.

Does anyone know how to get that working? Help would be greatly appreciated.

If nobody knows this, does anyone have any alternative solution? What I want is for example this: The entire screen is dark except a small area around the player which is not, but how dark it is is a function of time. I don’t really need any complicated dynamic lighting or anything like that. Just this simple feature. Has anyone done anything similar in their projects?

That tutorial code may not be the best way to do pixel manipulation. It
kinda assumes a few things about the pixel data that won’t be useful for
other data sources (e.g. other image files). Also, most people probably
shouldn’t use SDL_GetWindowSurface() ever. It’s more for specific
use-cases like for porting older games and doesn’t really work the way the
tutorial assumes (it’s not useful when you’re already using the render API).

Being quite biased, I would suggest SDL_gpu as a more capable alternative.
You can fill an image with black, then subtract out the alpha values to
make holes in it. You can use GPU_SetShapeBlendMode() with
GPU_BLEND_MOD_ALPHA or GPU_BLEND_SET_ALPHA and draw a filled circle on the
image for one way to do that.

Jonny D

Thanks for the input! I’ll look into it.

One way to do this with SDL would be to:

  1. Divide the scene into tiles
  2. Darken the far away tiles by modulating the color via SDL texture
    function (the name of which I cannot remember ATM)

Alternatively you could pre create a black image with transparency in the
centre and alpha blend it after rendering the scene. That will darken the
outside areas. And the centre will retain original color.On 15 Mar 2014 19:10, “Bananskrue” wrote:

If nobody knows this, does anyone have any alternative solution? What I
want is for example this: The entire screen is dark except a small area
around the player which is not, but how dark it is is a function of time. I
don’t really need any complicated dynamic lighting or anything like that.
Just this simple feature. Has anyone done anything similar in their
projects?


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

That’s a pretty good idea. Maybe if you generate a PNG screenshot of an
OpenGL lighting demo you could generate such images yourself. Maybe just
snipe them off the internet :slight_smile:

That’s not going to work for his original message’s goal: Multiple local
light sources.

Jonny D

Pallav Nawani wrote:

One way to do this with SDL would be to:

  1. Divide the scene into tiles
  2. Darken the far away tiles by modulating the color via SDL texture function (the name of which I cannot remember ATM)

I actually did this and it worked out well, the only problem was that rendering all of those extra tiles on-screen turned into quite a big change in performance, and the better I wanted this to function (I.E the lower the ‘blockyness’ of the lightsources) the worse it got. Your second idea is something I also considered but as Jonny D puts it this won’t work for mulitple light sources which would be moving relative to the player._______________________________________________
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)

[/quote][/quote]

You’re right. I think he and I are on the same path. I posted about my
problem but I can’t get anyone to answer, even after I simplified problem
to the beginning steps. Maybe if I repost so the title reflects the
absolute most simplicity someone will answer we can both get a leg up on
this issue

I’m sorry my phone mailed it out before I was done answering and editing.
Neither alpha transparency nor cutting little holes in it work where two
lights intersect over the background. At least that’s the result when tons
of other people have tried it and looked for help online. They had to
switch to the use of a surface and use opengl or whatever to light it in a
true way. I’ll repost and You have a look bananskrueOn Sun, Mar 16, 2014 at 2:35 PM, R Manard <@R_Manard> wrote:

You’re right. I think he and I are on the same path. I posted about my
problem but I can’t get anyone to answer, even after I simplified problem
to the beginning steps. Maybe if I repost so the title reflects the
absolute most simplicity someone will answer we can both get a leg up on
this issue

Using GPU_BLEND_MOD_ALPHA would work for overlapping light sources. It
multiplies the alpha value you use, so you can get lighter (more
transparent) areas from multiple lights.

Be cautious about your approach to lighting with OpenGL. Like I said
before, the most effective dynamic 2D lighting is done nowadays with
shaders. If you do 3D lighting, then you should also expect to use
shaders. The old way of fixed-pipeline lighting was actually pretty
limited. You had to do a lot of extra work to get reasonable shadows or
else you have lights shining through surfaces (because the API doesn’t have
any concept of shadowing). That’s not to mention the fact that you have to
generate 3D geometry to do 3D lighting and shadows. For a 2D game, that’s
often a lot of extra work.

Jonny D

Bananskrue wrote:

I can change an area of pixels from any color to a different color but i cannot give them alpha transparency. What am I missing?

Hiya Banan,
regards pixel transperancy you might want to check that any surfaces you’re working with match the format as supplied by SDL_QueryTexture.

Secondly, have you thought about using a singular 16x16 texture and merely changing the transparency of it using SDL_SetTextureAlphaMod while blitting your transition?
I’m not sure of the overhead of using SDL_SetTextureAlphaMod but I imagine it’s less than using 3000 textures.

You could also use a singular large black texture the size of the screen and use an SDL_Rect with SDL_RenderCopyEx to cover the areas which you know are completely black and not transitioning, rather than using many smaller texturecopies to achieve the same result.

In short, there’s plenty of options there if you get creative.

Hope I haven’t misunderstood your question and hope this helps.
On the flipside the discussion has also turned up some annoying truths about using large texture atlases for me.