Why change the color parameter values?

First, congrats on getting graphics 2.0 into public beta.  I know this has been a ton of work to get to this point and it looks very, very cool.  Can’t wait to play with some of the new features.

But reading over the changes and additions one bugaboo stood out to me:  You changed RGBA parameters from 0 - 255 to 0 - 1.  Why, oh why??

Reasons this change is no good:

  1.  I am used to the old way.  Old habits are hard to break.  Old people like me have a hard time retraining our brains.

  2.  I am an artist by trade and have been using RGB values of 0-255 since before Photoshop had layers.  In fact, I still use PS to figure out my RGB values for colors I use in Corona.  PS’s color picker popup uses several different methods to numerically represent a particular color, but none of them are RGB using 0-1! I will need to break out the calculator now to figure out the RGB value conversion.  Ugh.

  3.  This will break old code examples.  Yes, I saw the compatibility mode flag that will let the old way continue to work with old graphics 1.0 methods but to me this says you guys already _know _changing the color ranges will cause problems.

  4.  Even with compatibility mode on, mixing 1.0 and 2.0 features means mixing 0-255 and 0-1 in the same code.  That will make my brain explode.

So, again, why, oh why change it at all???

I realize there must be a very, very good reason for this change.  I’d love to know what it is.  But if there isn’t, or it’s an easy fix to revert everything back to good 'old 0-255, I cast my vote in favor!  

Thanks for listening to my rant.

-Stephen

Hi Stephen.  This is a topic that got discussed a lot among the team.  There were good arguments doing it both ways.  But in the end, we want to eventually start supporting more than 8 bit’s per channel, like 16 and 32 bit per channel images.  That can’t be done as long as we are locked into the 0-255 range.  We have to change at some point.  We can do it now or later, but the longer we wait, the harder it will be to change.

As you pointed out, there is the version 1 compatibility flag.  With this, your legacy apps should continue to function and as you start building new apps, you can use the new style.  Only if you want to move an existing app to graphics 2.0 then you can convert to the 0-1 range, you can quickly go through and add divide by 255 variables:  i.e:

:setFilllColor( 224/255, 128/255, 0/255) to convert to the new scale.   The V1 compatibility flag will also be important if you’re using setReferencePoint() frequently too.

Thanks for the explanation, Rob.  I figured there was a good reason, and supporting more bits per channel is about as good as they come.  My brain will still explode (even with the nifty divide by 255 trick), but at least I know it’s for a good cause.

You could create a fixColour function, something like this (psuedo code only, no guarantees it works):

[lua]local function fixedColor( col )

    for i = 1, math.min( #col, 3 ) do

        col[i] = col[i] / 255

    end

end[/lua]

This code idea requires 2 things:

  1. colours are stored in tables and

  2. you call this routine only once per colour table (as it affects the direct values)

So you could then do something like:

[lua]local mycol = { 0, 255, 255, 0.5 }

fixedColor( mycol )

rect:setFillColor( unpack( mycol ) )[/lua]

Using unpack means you don’t need to worry about how many indexes your colour tables contain (they could contain 1, 3 or 4 for greyscale, colour, and colour with alpha respectively) - the fixedColor() handles all types.

EDIT - or even simpler, create a function that you use to create your colours, something like…

[lua]local function newColor( … )

    local col = {}

    for i = 1, arg.n do

        if i < 4 then col[i] = arg[i] / 255

        else          col[i] = arg[i] ; end

    end

    return col

end[/lua]This way you can just do:

[lua]local mycol = newColor( 0, 255, 255, 0.5 )

rect:setFillColor( unpack( mycol ) )[/lua]

or even roll it all into a single line:

[lua]rect:setFillColor( unpack( newColor( 0, 255, 255, 0.5 ) ) )[/lua]

You could remove the need for the unpack() by making newColor return i[1], i[2], i[3], i[4] instead, but you’d get no real re-use from your colour objects (may or may not be desirable depending on your app needs).

Hi Stephen.  This is a topic that got discussed a lot among the team.  There were good arguments doing it both ways.  But in the end, we want to eventually start supporting more than 8 bit’s per channel, like 16 and 32 bit per channel images.  That can’t be done as long as we are locked into the 0-255 range.  We have to change at some point.  We can do it now or later, but the longer we wait, the harder it will be to change.

As you pointed out, there is the version 1 compatibility flag.  With this, your legacy apps should continue to function and as you start building new apps, you can use the new style.  Only if you want to move an existing app to graphics 2.0 then you can convert to the 0-1 range, you can quickly go through and add divide by 255 variables:  i.e:

:setFilllColor( 224/255, 128/255, 0/255) to convert to the new scale.   The V1 compatibility flag will also be important if you’re using setReferencePoint() frequently too.

Thanks for the explanation, Rob.  I figured there was a good reason, and supporting more bits per channel is about as good as they come.  My brain will still explode (even with the nifty divide by 255 trick), but at least I know it’s for a good cause.

You could create a fixColour function, something like this (psuedo code only, no guarantees it works):

[lua]local function fixedColor( col )

    for i = 1, math.min( #col, 3 ) do

        col[i] = col[i] / 255

    end

end[/lua]

This code idea requires 2 things:

  1. colours are stored in tables and

  2. you call this routine only once per colour table (as it affects the direct values)

So you could then do something like:

[lua]local mycol = { 0, 255, 255, 0.5 }

fixedColor( mycol )

rect:setFillColor( unpack( mycol ) )[/lua]

Using unpack means you don’t need to worry about how many indexes your colour tables contain (they could contain 1, 3 or 4 for greyscale, colour, and colour with alpha respectively) - the fixedColor() handles all types.

EDIT - or even simpler, create a function that you use to create your colours, something like…

[lua]local function newColor( … )

    local col = {}

    for i = 1, arg.n do

        if i < 4 then col[i] = arg[i] / 255

        else          col[i] = arg[i] ; end

    end

    return col

end[/lua]This way you can just do:

[lua]local mycol = newColor( 0, 255, 255, 0.5 )

rect:setFillColor( unpack( mycol ) )[/lua]

or even roll it all into a single line:

[lua]rect:setFillColor( unpack( newColor( 0, 255, 255, 0.5 ) ) )[/lua]

You could remove the need for the unpack() by making newColor return i[1], i[2], i[3], i[4] instead, but you’d get no real re-use from your colour objects (may or may not be desirable depending on your app needs).

hi, all, just posted a tutorial on this: http://www.ladeezfirstmedia.com/2013/11/21/tutorial-what-to-do-about-colors-in-the-new-corona-sdk-graphics-2-0-public-release/

Hi Jen,

Thanks for this excellent tutorial. I’ll be testing this method myself, in my own conversions. :slight_smile:

I just added the link to Corona University under “3rd-Party” in the “Images, …” section:

http://www.coronalabs.com/resources/tutorials/images-audio-video-animation/

Thanks,

Brent

Thanks Brent :slight_smile:

Here’s one you might consider adding to that same list, on content-scaling sprite sheets 

http://www.ladeezfirstmedia.com/2013/10/31/tutorial-image-scaling-with-texturepacker-corona-sdk/

:slight_smile:
J

Added! :wink:

I’m going to complain about this again because I feel it was a bad decision – and while I suspect the chances of Corona Labs “fixing” it by rolling back the change is slim, I feel a responsibility to speak up (with a proposed solution this time).

I don’t know of any game developers who think of colors in the range of 0-1 – which means when we get ready to set a color for something we have to use some other tool to figure out what the color number should be. And I don’t actually know if I have anything that will tell me 0-1 ranges, but I do know that just about EVERY paint program out there will tell the color in 0-255 range.

Solution: I believe setFillColor() should be returned to using ranges of 0-255 and if you want to use 16-, 32-, 64-bit colors, then a new setFillColorHD() API call can be added and that one can use the 0-1 ranges. There’s a precedent for that in display.newImage and display.newImageRect.

Thanks.

 Jay

PS - I decided to complain again because I’m writing new code and every time I come up against setFillColor() there’s no good+easy way to set the color.

PPS - Adding /255 to every color value is a kludge and offends me every time I resort to it, so it doesn’t fulfill the good part of good+easy.

Sorry to disappoint you (no offence) but you are totally wrong here saying that. It’s you and other Corona developers who are used to 0 ~ 255 color palette ( which is convenient because you can easily grab color from graphic program which I also find nice).

However, you must face some facts. Corona is based on OpenGL ( on simulator ) and OpenES ( mobile, a bit less powerful version, on device). This has been standard (next to later DirectX) for game industry for years and amount of games produced with it is tremendous. There color palette was always in 0~1 scale - so there is reason why for years it was kept the same in this matter (like for example supporting different color resolutions).

Corona Labs created (highly probably) 0~255 scale for filling for 2 reasons. For easiness for greater range of user and no need for greater resolution. But I bet that under the hood they were still dividing by 255 to get 0~1 to pass it to OpenGL.

As team said, they are now trying to support greater resolution of colors and Graphics 2.0 brought more OpenGL feature for developers, so they must have decided to get back to native color range for compatibility and unification reasons.

I’m not wrong because I said I don’t know of any game developers who think of colors in that way. It could be that I just don’t know the game developers you know. But my point was, and I’d bet money it’s right, that most devs don’t *think* of colors in that way. As in, come up with colors 0-1 in their heads.

And that has nothing to do with the solution that would have allowed 98% of Corona devs to continue using 0-255 while the ones who care about a larger color palette can do that, too:

setFillColor(0-255, …)

setFillColorHD(0-1, …)

Adding features is good. Breaking existing code is bad. I think CL could have gone to Gfx2 without breaking things – you can deprecate things over time and do an end-of-life later.

Example: object:setReferencePoint(display.CenterLeftReferencePoint) could have done an anchorX=0 and anchorY=.5 under the hood along with a warning that setRefPt was deprecated and to stop using it – but it would still work. That would have allowed maintenance and updates to go on for a while without things breaking.

Yes, it requires more back-end coding and yes, the resulting code is not as optimized as it could be, but that would only be a problem for the people who continue using the deprecated API calls.

 Jay

(Full disclosure – the changes hit me harder than the typical Corona dev (I think) because I make my living teaching game dev using Corona SDK. And the changes in the latest version basically put me out of business until I can recreate 100+ tutorial videos. So now I’m knee deep into that and every time I come across a change that wouldn’t have had to happen it frustrates me all over again and makes me think maybe being a janitor would be a less stressful way to make a living.)

 Jay

J.A., I agree that it’s sort of a hassle and we have to now edit our code (and your tutorials, that’s a mammoth task….)

It’s not really a question, though, of CL arbitrarily dreaming up one system or another. It’s just moving from the use of RGB Decimal to RGB Percent, both of which are used by various graphics programs. 

For example, http://www.colorhexa.com/271e94

This color is listed in several formats, Hex, RGB Dec, RGB %, and more.

I recommend in my tutorial above NOT dividing manually by 255 but just copying/pasting the percent value, edited to move the decimal place. There are other solutions like special libraries to use named colors, or whipping out your calculator and doing the math yourself…but in my opinion we might as well just make the change and hope we don’t have to ever do it again (right, CL? :slight_smile: )

I absolutely agree! CL seems to make these decisions pretty lightly without much consideration to the impact on their customer base.

Your proposed solution sounds awesome but I think this ship has sailed. I don’t expect CL to make any changes in this area. I feel for you and your 100+ hours of videos which now need to be updated. Best of luck. 

We don’t make these decisions lightly.  We understood fully that this would be a big impact on people and after considerable discussion from all people in the company, switching to 0…1 and providing graphicsCompatibility = 1 mode seemed to be the best of both worlds.  No one is forced to use 0…1 if they are vested in 0…255 for existing code.  If they want to use new features, then they have to change.

I feel bad for Jay and the other authors who v1 compatibility mode doesn’t help , but at the end of the day, it was the right direction for the future of the engine. 

Rob

I don’t know if this is of use to anyone but I’ve just updated the GGColour lib to use the new 0-1 values - https://github.com/GlitchGames/GGColour

Hey Graham, have you considered using the XWindows Color specifications for your color names and values?  See:

http://en.wikipedia.org/wiki/X11_color_names

This is a somewhat common definition of colors and names.

Rob