I have
unsigned char RGBA =[] { 255, 255, 255, 255 };
struct vector4 { float r, float g, float b, float a; } colour;
That's probably not valid C++, still
How do I set colour?
.
I have
unsigned char RGBA =[] { 255, 255, 255, 255 };
struct vector4 { float r, float g, float b, float a; } colour;
That's probably not valid C++, still
How do I set colour?
.
unsigned char RGBA[] = { 255, 255, 255, 255 };
struct vector4 { float r, float g, float b, float a; } colour;
float* ptr = (float*)colour;
for ( unsigned char i : RGBA )
*ptr++ = i / 255.f;
* UntestedBeautiful, thank you. I should know this..!
Actually come to think of it - what kind of cast should that be for a C++? Just a std::static_cast ?
On a more generic level, floating point color values range from 0.0 to 1.0, so all thats required is a simple scaling of the ratios. To squash anything to be between 0 and 1, just divide by the max value of that other thing. (There is slightly more work involved if the ranges don't both start at 0.0)
struct ColorRGBA
{
ColorRGBA(unsigned char rgba[4])
{
r = static_cast<float>(rgba[0]) / 255.0f;
g = static_cast<float>(rgba[1]) / 255.0f;
b = static_cast<float>(rgba[2]) / 255.0f;
a = static_cast<float>(rgba[3]) / 255.0f;
}
float r, g, b, a;
};
unsigned char RGBA[] = { 255, 255, 255, 255 };
ColorRGBA c = ColorRGBA(RGBA);
I don't believe the static cast is needed, unless your compiler has a nonstandard warning message.
Dividing the types char / float is going to follow a standards-required implicit conversion to make them the same types, float/float. Since the char value can be exactly represented by a float, no compiler message is required.
I'd argue that in the general case it would be better to use a solution with explicit static_casts as presented by ApochPiQ, because you can immediately see the four casts (and can also search for them), also making it easier to spot potentially expensive operations (load-hit-stores on PowerPC architectures).
But that's probably a matter of taste.
Okay a lot of replies and a lot to bear in mind - I'm young, I've cut my chops coding C-like languages a bit and I do need to know more about compilers I find. I just got my first job out of uni a few months ago and it sometimes feels like I just know nothing at all aha!
I like what you say about having explicit static_cast s -- I read Effective C++ recently. ApochPiQ - that looks perfect for my needs.
I like the ptr++ for-loop I must say - I get the impression it'd be fast, and it's pretty to look at, but it wouldn't let me cast with static_cast or (float*) -c-style cast, to cast the struct of floats to a (float*) - is this something to do with the virtual function table of the struct Colour ( since it has constructor, copy constructor, and a method) ? This is where a dynamic_cast comes in? And I don't really need it to be doing a dynamic cast, right?
I've deleted the code that I wrote based on the ptr++ approach so I'm unable to show you what I tried but it was pretty much verbatim - I didn't get to the for loop! (Oh yeah I'm using VS2010)
Essentially, the first post was an attempt to simplify:
class GLBitmap
{
private:
Pixel *pixels; // BYTE rgba[4]
int width;
int height;
...
public:
Pixel* FetchPixel( int x, int y )
{
return ( pixels ? &pixels[ (x * height) + y] : nullptr );
}
Usage:
const Pixel* pixel = bmp.FetchPixel(x, z); // GLBitmap bmp;
float r = b2f(pixel->R); // Did this macro work?
// Elsewhere:
inline float b2f(BYTE b) { return float(b / 255.0f); }
Turns out this inline float function 'just works' ?!
So is this an implicit static cast on the compilers request because it sees me not using static_cast<float>(b) ?
Edit - as you say - it 'just works' because a BYTE or unsigned fits a float, and that's kind of the point of bitmaps?
You do not need the explicit cast, and the explicit cast offers nothing other than extra typing. It is a standard behaviour of a C++ compiler to promote chars to floats in these calculations. The casts actually make it less readable imho, as they imply there's something non-standard going on and forces someone to parse it all with their eyes.
A straight forward rgba[ 0 ] / 255.0f etc. is plenty enough.imho
n!