Tutorial: A better way to store colors

Learn how to make certain types of games and use gameEditor.

Tutorial: A better way to store colors

Postby SuperSonic » Mon Mar 19, 2012 11:06 pm

NOTE: This tutorial is a little complicated so it is reccomended that you have a good understanding of c++ and math before reading :wink:

Hey all! :D

Ok, so I'm sure almost everyone here knows how to store an image in a 3d array right? So for example, let's say I was storing a 32x32 sprite. Here's what I would do:
Code: Select all
int MySprite[32][32][4];//This will store red, green, blue, and alpha
So anyways, this works fine for normal, simple stuff, but if you really look at it, it's just a memory waster. Why? Well, let me talk a little more about integers (int) first, and then I'll explain.

So integers are the standard method for storing numbers. A normal integer is composed of 4 bytes (or 32 bits). This means that it can store values from 0-4294967296. Yeah, that's a lot right? ^^. But the colors in Ge range from 0-255 (1 byte). This means that there is a 4294967040 difference between normal ints and colors. So in other words, when we store 4 ints (red, green, blue, and alpha), we are accessing 16 bytes of memory (128 bits), but we are only using 4 bytes (32 bits) of it. This means that there is a (calculating...) 3.40 E 38 difference (That's a ton). And if you multiply that by 32 and 32, well, I think you get the point ^^. So anyways, I found a really simple way around this.

Ok so if we have 4 colors, that makes 4 bytes right? And an integer is composed of 4 bytes right? RIGHT!!! So, let's say we take 4 numbers (each ranging from 0-255), and put them into one integer. How do we do that? Well, let's study some more and then I'll tell you =D

So, here's what an int looks like inside a computer when it's initialized:
Code: Select all
0000 0000 0000 0000
The 4 bytes are separated by spaces. So what if we stored our colors like this:
Code: Select all
ALPHA BLUE GREEN RED
Does this make sense?

Ok, how do we do this? Well, first of all, we know that in a computer, the number counting scheme goes from 1-256 and then restarts (This is like the roman counting scheme wich goes from 1-10 and restarts). So by multiplying a number (let's say 2) by 256, you can shift it's postition (Like if you multiplied 2 * 10, you'd move the two one place to the left). Here's an example:
Code: Select all
0000 0000 0000 0010
This is two
Code: Select all
0000 0000 0010 0000
This is two multiplied by 256

So can you see where I'm going here? We can simply use this "shifting" method to store all 4 numbers in the 4 bytes. So here's the code to do that:
Code: Select all
int StoreColors(int red, int green, int blue, int alpha)
{
    return (red) + (green * 256) + (blue * 256 * 256) + (alpha * 256 * 256 * 256);
}
So does this make sense to you (If it doesn't, just ask me about it :wink: )

So now we need code to retrieve it. I'm not going to explain all this because I'm way to tired xD. But if you read it line by line, you should be able to understand it
Code: Select all
int GetColor(int input, int color)
{
    int temp = input;
    for(int i = 0; i < color; i++)
    {
        temp /= 256;
    }
    for(int i = 0; i < color + 3 - (2 * id); i++)
    {
        temp %= 256;
    }
    return temp;
}
Ok so the way this works is, you give it the number that you're trying to get a color from, and then tell it which color (0 for red, 1 for blue, etc)

So here's some example code:
Code: Select all
int image[32][32];//Notice that we no longer have to add that extra 3. This saves us even more space
image[0][0] = StoreColor(255, 255, 0, 0);//Stores the color yellow =)
setpen(GetColor(image[0][0], 0), GetColor(image[0][0], 1), GetColor(image[0][0], 2), 0, 1);
putpixel(0, 0);


I hope this helps you guys, and thanks for reading :D

SuperSonic

EDIT* Ummm, after submitting this tutorial, I remembered that Ge deosn't store alpha as an int, it stores it as a float. So this code won't work with alpha (but it will with the other three colors)
A tree never hits an automobile except in self-defence.

Want to use your joystick or controller with Game Editor? Check out my controller engine =D
User avatar
SuperSonic
 
Posts: 1444
Joined: Fri Sep 24, 2010 9:24 pm
Location: Anywhere
Score: 72 Give a positive score

Re: Tutorial: A better way to store colors

Postby skydereign » Tue Mar 20, 2012 12:03 am

You can easily convert alpha either way (to float or to int). Since alpha is 0.0-1.0 just multiply it by 255 and round/cast it to get the rgb equivalent. And divide by 255 using float arithmetic to do the reverse.
User avatar
skydereign
 
Posts: 3394
Joined: Mon Jul 28, 2008 8:29 am
Score: 565 Give a positive score

Re: Tutorial: A better way to store colors

Postby Hblade » Tue Mar 20, 2012 2:46 am

+1
Subscribe to my YouTube? - Yes| No
User avatar
Hblade
 
Posts: 4345
Joined: Fri Dec 08, 2006 11:14 pm
Score: 167 Give a positive score

Re: Tutorial: A better way to store colors

Postby SuperSonic » Tue Mar 20, 2012 5:02 pm

skydereign wrote:You can easily convert alpha either way (to float or to int). Since alpha is 0.0-1.0 just multiply it by 255 and round/cast it to get the rgb equivalent. And divide by 255 using float arithmetic to do the reverse.
Haha, stop making me sound silly xD Just kidding :lol:

Hblade wrote:+1
Thanks =D
A tree never hits an automobile except in self-defence.

Want to use your joystick or controller with Game Editor? Check out my controller engine =D
User avatar
SuperSonic
 
Posts: 1444
Joined: Fri Sep 24, 2010 9:24 pm
Location: Anywhere
Score: 72 Give a positive score

Re: Tutorial: A better way to store colors

Postby Game A Gogo » Tue Mar 20, 2012 6:02 pm

Now, make the same thing, without using any multiplications or divisions!!!

hint: You'll need the bit-wise operators: << and >> ;3
Programming games is an art,
    Respect it.
User avatar
Game A Gogo
 
Posts: 3464
Joined: Wed Jun 29, 2005 10:49 pm
Location: French Canada *laughs*
Score: 181 Give a positive score

Re: Tutorial: A better way to store colors

Postby SuperSonic » Tue Mar 20, 2012 6:26 pm

Haha, I was thinking about that but I wasn't sure if Ge do it or not ^^

I may try that later though. Thanks :D
A tree never hits an automobile except in self-defence.

Want to use your joystick or controller with Game Editor? Check out my controller engine =D
User avatar
SuperSonic
 
Posts: 1444
Joined: Fri Sep 24, 2010 9:24 pm
Location: Anywhere
Score: 72 Give a positive score

Re: Tutorial: A better way to store colors

Postby Game A Gogo » Tue Mar 20, 2012 7:12 pm

here is something I sent LCL a while back, it explains a bit what you can do with << and >> with what you're doing, but it's not the same code :)

In a note to lcl, Game A Gogo wrote:void function(unsigned int Color)
{
unsigned char ColRed, ColGreen, ColBlue;
ColRed=Color>>16;
ColGreen=(Color<<16)>>24;
ColBlue=(Color<<24)>>24;
sepen(ColRed,ColGreen,ColBlue,0,​max(height,width));
}

If you need me to explain the bit operators, it's not as complicated as it seems!

So how do you set colors with that Color variable? easy! You can open up windows calculator, make sure it's on scientific!
You'll need to get used to hexadecimals... put the calculator in HEX mode and simply put 6 character. from 000000 to FFFFFF, the first being black and the second being white. the first two digits (FF0000) is red, the second two digits (00FF00) is green and finally the third two digits (0000FF) is blue!
If you don't know what number to put in, you can open up another instance of the calculator to transform DEC to HEX (from 0 to 255 to make something from 00 to FF)
now that you got your 3 byte hex number like 7F7F7F (gray), simply change to DEC and that's the value you'll put in for Color like 8355711 (gray)

now if you check the BIN, I will explain how the << and >> works!
<< pushes all the bit to the left
>> pushes all the bit to the right
so if you take FFFFFF (white) for exemple you get this:
1111 1111 1111 1111 1111 1111
the packs of four bits (individual digit, 1 or 0) are one digit in hex (So 1111 = F or 15)
doing Color<<4 will make it look like this:
1111 1111 1111 1111 1111 1111 0000
Notice the 0 being added? That's because we're moving the information to the left by 4 bits :D

and doing Color>>4 results to:
0000 1111 1111 1111 1111 11111
Information got lost! This sounds useless... but you can use it to isolate each numbers in the variable.
You can also loose information by doing <<, it depends on the size of the variable you're working with. Think of it as a table, where if you push something beyond the edge, it falls :)
Programming games is an art,
    Respect it.
User avatar
Game A Gogo
 
Posts: 3464
Joined: Wed Jun 29, 2005 10:49 pm
Location: French Canada *laughs*
Score: 181 Give a positive score

Re: Tutorial: A better way to store colors

Postby SuperSonic » Tue Mar 20, 2012 8:49 pm

Oh, that's cool :P
A tree never hits an automobile except in self-defence.

Want to use your joystick or controller with Game Editor? Check out my controller engine =D
User avatar
SuperSonic
 
Posts: 1444
Joined: Fri Sep 24, 2010 9:24 pm
Location: Anywhere
Score: 72 Give a positive score

Re: Tutorial: A better way to store colors

Postby lcl » Tue Mar 20, 2012 10:27 pm

Hey very great tutorial SuperSonic! =D
I just can't understand all of the caluclations... D= got to try and take some time to learn them =D

One thing I'd like to say..
There is another way to save space when loading images, don't use ints, because, as you said, they are way larger than needed.
Use unsigned chars instead, they are limited to 255. If you make unsigned char equal to 256 it will be actually equal to 0, if 257 it will be 1 etc. that's because it resets at 256. Isn't that just perfect for storing numbers from 0 to 255? =D

It can't handle negative numbers, of course, because it is unsigned, but we don't need it to handle negative numbers when we are dealing with image colours =D
This way we can save a lot space too! :)

Little calculations..
An integer array like this:
Code: Select all
int array[32][32][4]

is 16 384 bytes while unsigned char array like this:
Code: Select all
unsigned char array[32][32][4]

is only 4 096 bytes.

AND actually, with your method which uses ints (int array[32][32]) the amount of bytes used is just the same as using the array of unsigned chars as above! =DDDD
ERROR: -Couldn't find "world-dominating bunny"-

SABRE - 3D raycasting engine for GE!
LCL Games LCL Games on Facebook
User avatar
lcl
 
Posts: 1775
Joined: Thu Mar 25, 2010 5:55 pm
Location: Finland
Score: 192 Give a positive score

Re: Tutorial: A better way to store colors

Postby SuperSonic » Wed Mar 21, 2012 2:07 pm

Thank you lcl +1 :wink:
A tree never hits an automobile except in self-defence.

Want to use your joystick or controller with Game Editor? Check out my controller engine =D
User avatar
SuperSonic
 
Posts: 1444
Joined: Fri Sep 24, 2010 9:24 pm
Location: Anywhere
Score: 72 Give a positive score

Re: Tutorial: A better way to store colors

Postby tim4 » Sat Apr 14, 2012 3:06 am

You guys are amazing! I love how this forum has such intelligent convo...

Yeah, using those extra bytes in ints and even unsigned chars... gotsa remember this stuff! +1! :)
User avatar
tim4
 
Posts: 12
Joined: Mon Apr 09, 2012 4:55 am
Score: 9 Give a positive score

Re: Tutorial: A better way to store colors

Postby SuperSonic » Sun Apr 15, 2012 7:33 pm

Thank you Tim! :D

Oh but, I found a bug in my code and I forgot to post it. You have to change "int GetColor" to "unsigned int GetColor" or else, you may get wierd results ^^
A tree never hits an automobile except in self-defence.

Want to use your joystick or controller with Game Editor? Check out my controller engine =D
User avatar
SuperSonic
 
Posts: 1444
Joined: Fri Sep 24, 2010 9:24 pm
Location: Anywhere
Score: 72 Give a positive score


Return to Tutorials

Who is online

Users browsing this forum: No registered users and 0 guests