Sign in to follow this  
Followers 0
mynameisnafe

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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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.
4

Share this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
Share on other sites
I don't really care if the cast is "necessary." I still like having it there because implicit type conversions are evil and stupid, and having the cast relieves me from having to remember the inane C++ implicit conversion rules every time I visit the function.

Just a personal preference thing.


*shrug*
3

Share this post


Link to post
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 this post


Link to post
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

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0