IGAD Tutorial - Part 9 Assignment

8060f823d3b004e7f088076ae8a159c7
0
TheJjokerR 101 Nov 24, 2010 at 15:33

Well, here I am again :P

This time I’m quite confused by what is happening in this assignment:

http://www.devmaster.net/articles/intro-to-c++-with-game-dev/part9.php

Here’s what I got:

Sprite theSprite( new Surface("assets/ctankbase.tga"), 1 );
int alpha = 255;

void Game::Tick( float a_DT )
{
    m_Screen->Clear( 0 );
    
    if( alpha <= 0 ) return;
    
    theSprite.Draw( 0, 0, m_Screen );
    
    int mask = alpha << 24;
    
    Pixel* address = m_Screen->GetBuffer();
    for ( int i = 0; i < 640*480; i++ ){
        int color = address[i];
        int masked = (color & mask);
        address[i] = masked;
    }
    
    alpha = alpha - 5; //Decrease it (slowly)
}

The 24 you see in the mask variable works when it is 16(fades in red), 8(fades in green) or 0(fades in blue), though 24 wont work for some reason.

So my question is, why would it not work? I thought that if I make the mask at the alpha channel, and use the bitwise-& to extract the alpha channel, it’d fade out to black slowly.

I’ve also tried changing the RGB values to alpha, that way they do fade out, but in a weird way.

Thanks..

4 Replies

Please log in or register to post a reply.

A8433b04cb41dd57113740b779f61acb
0
Reedbeta 167 Nov 24, 2010 at 17:59

Alpha stored in the screen buffer doesn’t directly have any influence on how the image looks. It’s just an extra channel you can use to store additional information to use when doing image processing or compositing or some such.

Also, bitwise-ANDing the color with the alpha value is a bit weird. If you want to make something fade out the way to do that is multiply it by a value between zero and one. ANDing is not multiplying, so it’ll do strange things to the color.

For instance here’s how you’d fade the red channel:

float fade = 1.0f;

// for each pixel apply the fade to the red value
unsigned int color = address[i];
unsigned char red = color & 0x00ff0000;
unsigned char newred = (unsigned char)(red * fade);
unsigned int newcolor = (color & 0xff00ffff) | (newred << 16);
address[i] = newcolor;

// decrease fade for next frame
fade -= 0.02f;

I’m extracting the red component, fading it, then putting it back together with the other components (which are unchanged). To fade the image to black you’d do this for each of the red, green, and blue components separately.

46407cc1bdfbd2db4f6e8876d74f990a
0
Kenneth_Gorking 101 Nov 25, 2010 at 17:20

@Reedbeta

float fade = 1.0f;

// for each pixel apply the fade to the red value
unsigned int color = address[i];
unsigned char red = color & 0x00ff0000;
unsigned char newred = (unsigned char)(red * fade);
unsigned int newcolor = (color & 0xff00ffff) | (newred << 16);
address[i] = newcolor;

// decrease fade for next frame
fade -= 0.02f;

You forgot to shift the red value down to the first 8 bits ‘(color & 0x00ff0000)>>16’

Also, why the use of floating-point numbers? The byte->float->byte cast is probably costing alot of cycles. A good old modulate will work just as well, and without the conversions:

unsigned int fade = 255;

// for each pixel apply the fade to the red value
unsigned int color = address[i];
unsigned int red = (color & 0x00ff0000) >> 16;
unsigned int newred = (red + fade)>>1;
unsigned int newcolor = (color & 0xff00ffff) | (newred << 16);
address[i] = newcolor;

// decrease fade for next frame
fade -= 5;
A8433b04cb41dd57113740b779f61acb
0
Reedbeta 167 Nov 25, 2010 at 18:48

Ah right, thanks. But what’s this ‘modulate’ operation? Does (red + fade) >> 1 implement a multiplication? I don’t see how that works. Anyway, you could certainly do this with fixed-point math, e.g. (red * fade) >> 8, for speed. I figured using floating point was simpler and clearer, that’s all. ;)

46407cc1bdfbd2db4f6e8876d74f990a
0
Kenneth_Gorking 101 Nov 26, 2010 at 08:03

@Reedbeta

But what’s this ‘modulate’ operation? Does (red + fade) >> 1 implement a multiplication? I don’t see how that works. Anyway, you could certainly do this with fixed-point math, e.g. (red * fade) >> 8, for speed.

I think that is what it is called, I remember it from the olden days, when fiddling around with mmx. It may be something completely different :)

Actually, now that I think about it, that just does a 50% blend between the two values. The ‘(red * fade) >> 8’ you suggested is what I was thinking of.