Sign in to follow this  
Spa8nky

[XNA] Color struct and switch statements

Recommended Posts

If I have an array of colours, how can I use a switch statement with the colour returned from the current array index?
            Color[] pixels = new Color[width * height];
            texture_Tiles.GetData(pixels);

            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    int i = y * width + x;

                    Color colour = pixels[i];
                    switch (colour)
                    {

                    }
...........................

I currently get the following error message: "Error 5 A value of an integral type expected" Does this mean there is no way to do this using a switch statement? Thank you.

Share this post


Link to post
Share on other sites
What would you like to do in the "case" parts of the switch command? You want to compare the current color with a set of few specific colors and do something else for lets say white, black etc?

Isn't it possible to convert the Color struct to DWORD? DWORD (0xFFFFFFFF for white etc.) can be used as the condition in switch command.

Share this post


Link to post
Share on other sites
A switch statement (as the error indicates) compares numbers. Color is a structure.

switch( value ) is equivalent to:

if( value==firstValueToCheck ) {...}
else if( value==secondValueToCheck ) {...}
....

You'll need to select some member of Color to check, or calculate the value you want to check, and switch on that value. The value has to be an integer, unsigned int, unsigned char, etc.

Share this post


Link to post
Share on other sites
I was thinking about switch simply from a readiblity point of view as I didn't like the idea of if else.

I could use the packed value of the colour:


uint packedColor = color.PackedValue;

Color unpackedColor = new Color();

unpackedColor.B = (byte)(packedColor);

unpackedColor.G = (byte)(packedColor >> 8);

unpackedColor.R = (byte)(packedColor >> 16);

unpackedColor.A = (byte)(packedColor >> 24);


Is that wise, or does it make it less readable than simple if else statements?

Share this post


Link to post
Share on other sites
Cannot you simply use the packed value in the switch statement?
switch (color.PackedValue)
{
...
}

I don't know XNA and its Color structure, but wouldn't this work?

[Edited by - Tom KQT on February 21, 2010 12:35:33 PM]

Share this post


Link to post
Share on other sites
Quote:
calculate the value you want to check, and switch on that value. The value has to be an integer, unsigned int, unsigned char, etc.

My if() else if() was meant just to show the equivalent of the switch. I wasn't recommending it. Sorry about the confusion.

I think Tom KQT and I are saying the same thing. Use your calculated value for the switch.

And why not uint packedValue = Color.b + Color.g << 8 + Color.r << 16 ...?

switch(packedValue) ...

Share this post


Link to post
Share on other sites
Can someone explain what is happening here please?

Is the following method correct for obtain the packed number?

Packed values (R + G + B + A)

B (Unpacked) = (byte)(packedColor); [0, 255] +
G (Unpacked) = (byte)(packedColor >> 8); [0, 255] +
R (Unpacked) = (byte)(packedColor >> 16); [0, 255] +
A (Unpacked) = (byte)(packedColor >> 24); [0, 255]

If it is then why isn't solid black (0,0,0,255) 255 >> 24?

It is: 4278190080

In other words:


uint colour = pixels[i].PackedValue;
switch (colour)
{
case (255 >> 24):
{
Console.WriteLine("Black");
break;
}
}


doesn't work and says 255 >> 24 is 0.

Share this post


Link to post
Share on other sites
Spa8nky, the code you posted isn't very clear, I'm afraid. Not sure what the "[0,255]+" stuff is, or what you mean by Packed values(...).
Quote:
If it is then why isn't solid black (0,0,0,255) 255 >> 24?

The packed color is blue + green << 8 + red << 16 + alpha << 24. Left bitshifts.

Black would be 255 << 24 = 0xFF000000. Convert 0xFF000000 to decimal and that's 4278190080.

Looks like you have your bitshifts in the wrong direction.

EDIT: you gotta think in binary.

255 = 0xff = 11111111
0xff >> 1 = 01111111
0xff >> 2 = 00111111
oxff >> 3 = 00011111
...
0xff >> 7 = 00000001
oxff >> 8 = 0 // all gone
oxff >> 24 = 0 // all gone long ago


[Edited by - Buckeye on February 21, 2010 4:45:17 PM]

Share this post


Link to post
Share on other sites
That's what has confused me with the shifting direction.

0xFF << 24 does not return 4278190080 in the switch statement?

I get the following error message instead:

Constant value '-16777216' cannot be converted to a 'uint' when used in a switch statement.

I assumed -ve value meant I was shifting in the wrong direction at first, but is the number wrapping or is something else happening here?

EDIT:

I can use the hexadecimal values with no problems though:


// [Packed colour values]
// • uint value = (B + G << 8 + R << 16 + A << 24)
// • Hex value = 0xAARRGGBB
//
// Where:
// AA = Alpha Value = [0, 255] = [00, FF]
// RR = Red Value = [0, 255] = [00, FF]
// GG = Green Value = [0, 255] = [00, FF]
// BB = Blue Value = [0, 255] = [00, FF]
uint colour = pixels[i].PackedValue; // 4278190080
switch (colour)
{
case (0xFF000000):
{
Console.WriteLine("Black");
break;
}
}

Share this post


Link to post
Share on other sites
You can think of more things to do the hard way than anyone I've ever seen.

The value you're looking for is, as mentioned above, 0xFF000000. Or, you might try uint(255 << 24) if you really want to (don't know if your compiler will take that), or you might try 4278190080. You need to try different things yourself once in a while.

If you have a calculator program that can convert decimal to hex and back, see what -16777216 is in hex.

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