Followers 0

Simple Question BYTE->float C++

11 posts in this topic

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?

.

0

Share on other sites
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;

* Untested
* Subject to compiler scrutiny; check generated assembly
0

Share on other sites

Beautiful, 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 ?

Edited by mynameisnafe
0

Share on other sites

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)

Edited by ferrous
2

Share on other sites

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.

1

Share on other sites

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?

Edited by mynameisnafe
0

Share on other sites

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!

0

Share on other sites

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?

No, it has nothing to do with virtual function tables or dynamic_cast. It's because colour is a struct and (float*) is a pointer. If you really want to do this cast, the C-style cast or a reinterpret_cast should work on the address of colour, (&colour), though I don't really recommend doing this. You could use a union inside colour if you want it to have 4 floats that are also used as an array.
0

Share on other sites

I was just looking for the simplest way really..

ApochPiQ's first post covers that - I'll be using it often so I know what it's for. I saw a macro somewhere that converted an int to 3 floats - that was cool - but right now, I just want to look at some pixel's colour in Visual Studio! Thanks guys

0

Create an account

Register a new account