View Single Post
Old 05-09-2016, 05:20 PM   #3
Human being with feelings
Lokasenna's Avatar
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,241

2. Colors

On to the, er, slightly less boring stuff. Drawing things! Yay! And of course, when you're drawing, the first question to ask yourself is "what color feels most like the particularly annoying shade of ennui I feel reading this forum post?"

Again, some of these parameters are optional. R, G, and B are the components of our color, expressed here as a decimal from 0 to 1. 1,1,1 is white, 1,0,0 is red, and so on. Tagging along with them is A, which stands for alpha. Alpha refers to the transparency of an image or, in this case, the drawing we'll be doing. 1 is opaque, 0 is transparent, 0.5 is see-through.

Mode refers to the blending mode, which any Photoshop user will be familiar. This determines how the pixels we draw combine with those already in our window. For the most part it's irrelevant to us, but some fancier effects would definitely make use of it. The final parameter, Dest, lets you draw to the things other than the main window. Again, for basic stuff it's not at all necessary, but it has a few really handy uses that we might get to if I can stay interested in writing these tutorials long enough.

gfx.set(1, 0.5, 0.5, 1)
That's a lovely shade of... uh... I guess "salmon"?. Or "sunburn", maybe? It's definitely A color, at any rate. Readers who don't know computer colors from a hole in the ground - and why you can't tell the difference there is a good question for you therapist - are kindly directed to this site I just found:

(Pause for a brief interlude...)

Color conversion:
- For anyone like me who prefers to work with their colors as good ol' 8-bit values like 255, 128, 128 just divide your value by 255 to get the 0-1 equivalent. Personally, I write all of my functions and classes to take 8-bit as their input and then immediately convert it just so I never have to think about it.

- For those used to working with hexadecimal values, as is typical on the Information Superhighway, here's a useful helper function I found on Google:
-- Convert a hex color to integers r,g,b
local function hex2rgb(num)
	if string.sub(num, 1, 2) == "0x" then
		num = string.sub(num, 3)

	local red = string.sub(num, 1, 2)
	local blue = string.sub(num, 3, 4)
	local green = string.sub(num, 5, 6)
	red = tonumber(red, 16)
	blue = tonumber(blue, 16)
	green = tonumber(green, 16)
	return red, green, blue

-- And you would call it like so:
local hex_color = 0xFF8080
local r, g, b = hex2rgb(hex_color)

gfx.set(r, g, b, 1)
"But wait!", I hear you yelling at your monitor, "what about the background color! It's just a black void and that terrifies me just like the ancient Babylonians were afraid of zero!" No sweat.


Two things of note here - firstly, this is a variable and not a function. Second, the color format is completely different for reasons known only to God and Justin Frankel, assuming you aren't of a religious persuasion that considers them one and the same.

(I'm positive there's a Dalai Llama joke to be made here, but it just isn't happening)

Rather than 8-bit RGB or 0-1, this packs all three values together into one integer. The number itself is a direct translation of its hex equivalent, minus the "0x" prefix. Confused? I know I was for a while.

As the above description states, this number is equal to R + (G * 256) + (B * 256 * 256). To whit, another helper function:
-- Take discrete RGB values and return the combined integer
-- (equal to hex colors of the form 0xRRGGBB)
local function rgb2num(red, green, blue)
	green = green * 256
	blue = blue * 256 * 256
	return red + green + blue


-- Again, used like so:
local r, g, b = 255, 128 128
local color_int = rgb2num(r, g, b)
It should spit out 16744576, the same sexy shade of too-much-time-in-the-sun we previously expressed as 0xFF8080, 1, 0.5, 0.5, and 255, 128, 128. Who knew there were this many different ways to specify a color? Also, gfx.clear will default to black if you don't specify anything.

Anyway, back to the whole reason we needed this conversion to start with:

local function Main()
    ...defer() loop and maintaining the window go here...

-- A nice, respectable shade of grey.
local r, g, b = 64, 64, 64
gfx.clear = rgb2num(r, g, b)

gfx.init("My Window", 640, 480, 0, 200, 200)
So there you go. Colors. *cue "yaaayyy..." sound from Monty Python & The Holy Grail*

Last edited by Lokasenna; 08-03-2016 at 04:11 AM.
Lokasenna is online now   Reply With Quote