# using hex color codes

being a complete newb, i apologise beforehand if this question is too stupid.
whenever i need to set color to any object, i use RGBA values like material.setAmbient(VBase4(R,G,B,A)).

the values of RGBA being between 0-1 with single digit precision, i feel this restricts a lot of color choices for me.

is it possible to use hex colors instead of the RGBA scheme? i read somewhere that RGBA is how the graphics cards read colors but wanted to make sure of it.

By “single digit” you mean like 0.1? If so, then no, that’s not the case. That way you would have only 10 possible values per color channel, which is way too few. Instead, you have 256 values, just like with any other representation, so 1.0 means 255 or 0xff. No difference at all, just another way of writing the same thing.

If, however, you want to use 0-255 or 0x0-0xff representation for pure convenience reasons, you can do it too. For instance:

``````def hexColor(hexr, hexg, hexb, hexa):
hc = [hexr, hexg, hexb, hexa]
color = Vec4()
for i in range(4):
color[i] = 1.0 / float(int(hc[i], 16))``````

It can be written better, so you can pass the whole hex value instead of per channel, but that’s just a quick example.

``colour = VBase4(0xFF / 255.0, 0xC5 / 255.0, 0x7A / 255.0)``

@copper: can you elaborate a bit? so far i have only used values like 0.1, 0.2…0.9, 1 for my RGBA channels.This gives a color range of 111111 colors.
how can i use 256 colors per channel?

eg.
R - 145
G - 205
B - 16

How do i use this in my color function?
will it be valid to use;
material.setAmbient(VBase4(145,205,16,A))?
when I try this, i get all whites.

If i use values like 0.245, its output is same as 0.2

The function that i use to convert hex to single precision decimal is:
def colorHexToRGBA(self, colorHex):
RHex = str(colorHex)[:2]
GHex = str(colorHex)[2:4]
BHex = str(colorHex)[4:]
RFloat = int(RHex, 16)/255.0
GFloat = int(GHex, 16)/255.0
BFloat = int(BHex, 16)/255.0
return “%.1f” % round(RFloat,2), “%.1f” % round(GFloat,2), “%.1f” % round(BFloat,2)

Try running this code along with some color picker (like gcolor2, if you’re on Linux). It fills the screen with black and increases the red channel value by 1.0/255.0 whenever you press “v” on your keyboard. Press “v” and check the displayed color with the color picker. You will see that the value goes through the whole spectrum.

``````from direct.directbase import DirectStart
from panda3d.core import *

import sys

class prototype(object):
def __init__(self):
c = CardMaker("name")
c.setFrame(-1, 1, -1, 1)

self.cn = NodePath(c.generate())
self.cn.reparentTo(render2d)

self.i = 0.0
self.v = 1.0 / 255.0

base.accept("v", self.incColor)

self.incColor()

def incColor(self):
print self.v * self.i

self.cn.setColor(Vec4(self.v * self.i, 0, 0, 1))
self.i += 1.0

base.accept("escape", sys.exit)
p = prototype()
run()``````

Obviously, these values need to be in the 0.0 - 1.0 range.

Single precision float doesn’t mean one decimal place.

Thanks. I think i got it now.
the function for color can interpret values with 3 decimal places.
so
material.setAmbient(VBase4(0.123,0.478, 0.991,A)).
will work.

EDIT: whoa. so there’s something called single precision float?! now what you said makes sense.

You should really stop thinking in terms of decimal places.

today is the first time i heard of single precision floats. all this time i thought it stood for decimals. time to hit the books.