Results 1 to 15 of 15

Thread: Alpha layer and fog of war

  1. #1

    Default Alpha layer and fog of war

    I am trying to implement a fog of war. I have done so using some very clunky black rectangles over a tilemap. I am looking to make something more fluid and visually appealing. Some searching has revealed that their maybe the possibility of using a large black texture and applying alpha maps to it. I am not an opengl coder by any means. Does anyone have an example or page that I could read up on how I could accomplish this with clanlib calls? Thanks.

  2. #2
    ClanLib Developer
    Join Date
    May 2007
    Posts
    1,824

    Default

    This is the method I would use:

    Using GIMP or another graphics package that can draw onto the alpha (transparency) channel.

    Create a black image of 512 pixels by 512 pixels. This is the color the "fog" fades to
    Add an alpha channel to the image.

    I'm not sure about the next bit (without trying it out)
    Create a new white image of 512x512 pixels. Draw a gradient circle with the middle radius of 64x64 pixels at black, and gradient black to white to the border.
    Use GIMP "color to alpha" ( http://docs.gimp.org/en/gimp-layer-t...ency-menu.html ) to convert the image to an alpha channel.
    Copy just the alpha channel of this image to the alpha channel of the first image.
    Save as PNG

    In your application:
    Load the png as CL_Image or CL_Sprite and draw scaled to fit the entire window (whilst keeping the aspect ratio)

    So in the center of your image, the alpha is 0, therefore no black is drawn.
    In the middle of your image, the alpha is 0.5, therefore background blended with black
    In the edge of your image, the alpha is 1.0, therefore black is drawn.

    There are other ways to do this, but this is the easiest. For a top down game.

    It will not work on an isometric game. I would use an OpenGL glsl shader for that, using a height map. Or numerious other methods

  3. #3
    ClanLib Developer
    Join Date
    May 2007
    Posts
    1,824

    Default

    And also someone once did a "CanvasAdvanced" example in ClanLib - http://clanlib.org/wiki/File:Example_canvasadvanced.png that might also be helpful. I don't know the code, so it might not be helpful at all

  4. #4

    Default

    I had actually tried the same method as the canvas advanced but had no luck using this method when combining it with the GUI components. I will do a little more investigation into that code and see if I can combine the GUI and the canvas tutorial.

  5. #5

    Default

    So here is where I am at. My light object doesn't actually erase the texture but instead it looks like a gradient black circle.

    http://pastebin.com/5SUimHNN

    This stems from the canvasAdvanced tutorial so the files are the images located in the examples directory with the installed clanlib.

  6. #6

    Default

    In addition to the above code, I have tried adding the set_frame_buffer call but then none of the lightcontainer is drawn and anything after this doesn't draw.

  7. #7

    Default

    FYI, the light_container draw is called on a custom gui component who is set to repaint constantly.

  8. #8
    ClanLib Developer
    Join Date
    Sep 2006
    Location
    Denmark
    Posts
    554

    Default

    The problem is the blend function you specify:

    blender.set_blend_function(cl_blend_zero, cl_blend_one_minus_src_alpha, cl_blend_zero, cl_blend_one_minus_src_alpha);

    In math terms this translates to:

    dest.rgb = src.rgb * 0 + dest.rgb * 0;
    dest.a = src.a * (1-src.a) + dest.a * (1-src.a);

    If its the alpha channel of the texture you want to use as light blocker, then you want this math:

    dest.rgb = src.rgb * 0 + dest.rgb * (1-src.a);
    dest.a = src.a * 0 + dest.a * 1;

    Which becomes:

    blender.set_blend_function(cl_blend_zero, cl_blend_zero, cl_blend_one_minus_src_alpha, cl_blend_one);

    Or if its the RGB color of the texture you want to use as light blocker:

    dest.rgb = src.rgb * 0 + dest.rgb * src.rgb;
    dest.a = src.a * 0 + dest.a * 1;

    blender.set_blend_function(cl_blend_zero, cl_blend_zero, cl_blend_src, cl_blend_one);

    Hopefully this clears things up a bit.

  9. #9

    Default

    I'm starting to understand a little bit better thanks to your explanation. I did a little research on the opengl Blending formulas.

    Here are a couple questions mixed with some observations.

    Note that my graphics are a 256x256 Image with RGBA channels all set to white. My light source is a 256x256 image with a gradient on all RGBA channels from white to black. Let me know if I have something like my gradient backwards, which maybe the case if I read the earlier post correctly.

    Question 1. Does it really matter what color the image is if all I want to do is blend the alpha channels?

    If I want to disregard all RGB data, the first part of my formula looks like this.

    dest.rgb = src.rgb * 0 + dest.rgb * 0;

    If I want the gradient to cut away the all white image (essentially only using the alpha from the clip texture), I want to modify the second formula as follows.

    dest.a = src.a * 0 + dest.a * 1;

    Question 2. How do I know which is my src and which is my dest?
    Question 3. Is this simply draw order?
    Question 4. If I draw my giant white (turned black using CL_Texture::draw(0,0,0,255) first, is this considered to be the src when doing these formulas?

    So the pseudo code looks like this.

    gc.set_texture(0, fog);
    CL_texture::draw(0,0,0,255); // Fills screen with black
    gc.reset_texture();
    gc.set_blend()
    gc.set_texture(clip)
    CL_texture::draw(255,255,255,255); // black part of alpha channel cuts away the filled screen
    gc.reset_texture();

  10. #10

    Default

    A little investigation into this and it sounds like perhaps you have to do this on the frame buffer? However, doing so, prevents anything after that from being drawn properly when my game loop is inside the custom CL_guiComponent's onRender function.

    Edit: I am refering to using gc.set_frame_buffer(fb_lightmask); from the canvasAdvanced tutorial

  11. #11
    ClanLib Developer
    Join Date
    Sep 2006
    Location
    Denmark
    Posts
    554

    Default

    Quote Originally Posted by Casey Abernathey View Post
    Question 1. Does it really matter what color the image is if all I want to do is blend the alpha channels?
    No, it does not matter. The color of the source (the image) can be anything if the blend function doesn't use it.

    If I want to disregard all RGB data, the first part of my formula looks like this.

    dest.rgb = src.rgb * 0 + dest.rgb * 0;
    Actually, no. Dest is the current value in the frame buffer, which means a formula like the above will store black into the frame buffer regardless of any alpha values or any color values. In my first post I multiply the inverse source alpha (the image) with the dest rgb (current color in the frame buffer). The result is that a fully transparent (alpha = 0) pixel in the source image causes the dest color to be kept, while a fully opaque pixel (alpha = 1) makes the dest color black.

    I think what is probably confusing you is what dest and src is. Imagine we are drawing a textured rect (i.e. using CL_Draw::texture). Then for each pixel the rect covers we have a 'source' rgba pixel from the image, and a 'dest' rgba pixel from the frame buffer. The function then returns the new frame buffer value to be stored.

    Strictly speaking the source color is the fragment output value from the fragment shader program, which for all the high level functions you are using means it is the image/texture.

    Normal image transparency, like you see when using layers in GIMP, uses this blend function:

    dest.rgb = src.rgb * src.a + dest.rgb * (1-src.a)

    The value stored in dest.a usually doesn't matter that much unless you are rendering to a texture. I recommend that you simply keep dest.a. Its value is 1 in most cases.

    dest.a = src.a * 0 + dest.a * 1;

    Question 2. How do I know which is my src and which is my dest?
    Question 3. Is this simply draw order?
    Question 4. If I draw my giant white (turned black using CL_Texture::draw(0,0,0,255) first, is this considered to be the src when doing these formulas?
    Hopefully my explanation above about src and dest should answer this. The draw order affects what is in 'dest', bit like if you move layers up and down in photoshop or GIMP.

  12. #12
    ClanLib Developer
    Join Date
    Sep 2006
    Location
    Denmark
    Posts
    554

    Default

    Quote Originally Posted by Casey Abernathey View Post
    A little investigation into this and it sounds like perhaps you have to do this on the frame buffer? However, doing so, prevents anything after that from being drawn properly when my game loop is inside the custom CL_guiComponent's onRender function.

    Edit: I am refering to using gc.set_frame_buffer(fb_lightmask); from the canvasAdvanced tutorial
    There is always a frame buffer active. If you aren't setting one explicitly then the active frame buffer is the back buffer, which is what you want unless you are trying to render to a texture. Which you aren't in this particular instance.

  13. #13

    Default

    Fixed!

    I have to thank Judas for his loads of knowledge. I was finally able to make this work using the canvasAdvanced example and tons of information that Judas bestowed upon me. The key was to use the GuiManager Direct as Judas suggested. I will upload some code later on so that others in my same position of mixing frame buffers and gui components can have an example of what they need to do.

  14. #14
    ClanLib Developer
    Join Date
    May 2007
    Posts
    1,824

    Default

    Yeah, Judas is a very clever programmer. I didn't have a clue!

  15. #15
    ClanLib Developer
    Join Date
    Sep 2006
    Location
    Denmark
    Posts
    554

    Default

    Thank you for the kind words.

Similar Threads

  1. About entity layer control
    By youngvleo in forum Proton SDK
    Replies: 2
    Last Post: 01-15-2013, 03:46 PM
  2. Multipass render and alpha
    By Ockonal in forum Official ClanLib SDK Forums
    Replies: 0
    Last Post: 10-08-2010, 10:20 AM
  3. Premultiplication of RGB by Alpha.
    By rombust in forum Official ClanLib SDK Forums
    Replies: 6
    Last Post: 11-12-2009, 03:15 PM
  4. Canvas and alpha
    By marcr in forum Official ClanLib SDK Forums
    Replies: 0
    Last Post: 02-09-2008, 04:36 AM
  5. Weirdness with alpha
    By madmark in forum Official ClanLib SDK Forums
    Replies: 4
    Last Post: 12-12-2007, 11:08 PM

Bookmarks

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •