### Author Topic: Better Way to cycle through colors  (Read 4939 times)

0 Members and 1 Guest are viewing this topic.

#### Foaly

• Sr. Member
• Posts: 453
##### Better Way to cycle through colors
« on: May 22, 2012, 12:19:21 am »
Is there a better / more efficient way to cycle through all colors than this?!

// setup
sf::Color color;

//...
// update loop ( fTime is the elapsed frame time)

fRed = color.r;
fGreen = color.g;
fBlue = color.b;

if (fRed == 255 && fGreen < 255 && fBlue == 0)
color = sf::Color(255, fGreen + 25 * fTime, 0);
else if (fRed > 0 && fGreen == 255 && fBlue == 0)
color = sf::Color(fRed - 25 * fTime, 255, 0);
else if (fRed == 0 && fGreen == 255 && fBlue < 255)
color = sf::Color(0, 255, fBlue + 25 * fTime);
else if (fRed == 0 && fGreen > 0 && fBlue == 255)
color = sf::Color(0, fGreen - 25 * fTime, 255);
else if (fRed < 255 && fGreen == 0 && fBlue == 255)
color = sf::Color(fRed + 25 * fTime, 0, 255);
else if (fRed == 255 && fGreen == 0 && fBlue > 0)
color = sf::Color(255, 0, fBlue - 25 * fTime);

// now use the color somehow

#### Laurent

• Hero Member
• Posts: 32504
##### Re: Better Way to cycle through colors
« Reply #1 on: May 22, 2012, 08:12:59 am »
// combine the color components into a single integer
sf::Uint32 c = (color.r << 16) | (color.g << 8) | color.b;

// increment it
c += 25 * fTime;

// loop when max (white) is reached
if (c > 0x00ffffff)
c = 0;

// decompose into a new color
color.r = static_cast<sf::Uint8>((c & 0xff0000) >> 16);
color.g = static_cast<sf::Uint8>((c & 0xff00) >> 8);
color.b = static_cast<sf::Uint8>(c & 0xff);
Laurent Gomila - SFML developer

#### Foaly

• Sr. Member
• Posts: 453
##### Re: Better Way to cycle through colors
« Reply #2 on: May 22, 2012, 09:42:45 am »
Wow that is awesome. I would have never thought of that! Thanks for the quick reply! I'll try it as soon as I can.

#### Foaly

• Sr. Member
• Posts: 453
##### Re: Better Way to cycle through colors
« Reply #3 on: June 04, 2012, 07:25:45 pm »
Ok i gave your method a try, but all I got was a black screen. I wrote a minimal code (a coloured Circle follows the mouse), but its still all black. Do you know why?
#include <SFML/Graphics.hpp>

int main()
{
sf::RenderWindow window(sf::VideoMode(800, 600), "SFML works!");

sf::Clock FrameClock;
float fTime;

sf::CircleShape m_Circle(5);
m_Circle.setFillColor(sf::Color::Red);
sf::Color color;
sf::Uint32 c;

while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
// Close Event
if (event.type == sf::Event::Closed)
window.close();

// Escape key pressed
if ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Escape))
window.close();
}

fTime = FrameClock.restart().asSeconds();

// combine the color components into a single integer
c = (color.r << 16) | (color.g << 8) | color.b;

// increment it
c += 25 * fTime;

// loop when max (white) is reached
if (c > 0x00ffffff)
c = 0;

// decompose into a new color
color.r = static_cast<sf::Uint8>((c & 0xff0000) >> 16);
color.g = static_cast<sf::Uint8>((c & 0xff00) >> 8);
color.b = static_cast<sf::Uint8>(c & 0xff);

m_Circle.setPosition(sf::Mouse::getPosition(window).x, sf::Mouse::getPosition(window).y);
m_Circle.setFillColor(color);

window.clear();
window.draw(m_Circle);
window.display();
}

return 0;
}

#### Laurent

• Hero Member
• Posts: 32504
##### Re: Better Way to cycle through colors
« Reply #4 on: June 04, 2012, 09:13:36 pm »
25 * fTime is probably not greater than 1, so it's rounded to 0 because it's assigned to an integer. Try with bigger numbers.
Laurent Gomila - SFML developer

#### Foaly

• Sr. Member
• Posts: 453
##### Re: Better Way to cycle through colors
« Reply #5 on: June 05, 2012, 06:06:48 pm »
Yeah that makes sense... I tried bigger numbers (500 works well), but then I get another unexpected result: The color only changes between black and blue. The rest of the colors are never shown.

#### Laurent

• Hero Member
• Posts: 32504
##### Re: Better Way to cycle through colors
« Reply #6 on: June 06, 2012, 12:46:38 pm »
This is the expected result. This code will show all the blue values (0 - 255), then increment green, then show again all the blue values with green = 1, then increment green, etc. So you'll see green only after some time, and red after an even bigger amount of time.

Before finding a better solution, you need to define how you want to cycle through colors.
Laurent Gomila - SFML developer

#### Foaly

• Sr. Member
• Posts: 453
##### Re: Better Way to cycle through colors
« Reply #7 on: June 06, 2012, 10:46:40 pm »
aaaah ok I get it! Well yeah this is not exactly what I had in mind. Mean more of a transition of colors, like my code does above. The colors should go red, orange, yellow, green, light blue, dark blue, pink and back to red. Is that possible?

#### Foaly

• Sr. Member
• Posts: 453
##### Re: Better Way to cycle through colors
« Reply #8 on: June 12, 2012, 06:13:07 pm »
Does anybody something that would work?

#### eXpl0it3r

• SFML Team
• Hero Member
• Posts: 10782
##### Re: Better Way to cycle through colors
« Reply #9 on: June 13, 2012, 12:47:44 am »
The colors should go red, orange, yellow, green, light blue, dark blue, pink and back to red. Is that possible?

I bet it's possible but I'm not willing to spend my time on this purely logic part.
But I can advise you to take a sheet of paper and an image editor with a color circle and RGB hex 'output' and you can start trying to find a 'formula' on how to calculate the next color from the current color to get a nice transition. (Maybe you'll understand how to add/subtract only by moving the color selector on the color circle in your image editor. )
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

anything