Welcome, Guest. Please login or register. Did you miss your activation email?

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

0 Members and 1 Guest are viewing this topic.

Foaly

  • Sr. Member
  • ****
  • Posts: 453
    • View Profile
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

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
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
    • View Profile
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
    • View Profile
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

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
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
    • View Profile
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

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
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
    • View Profile
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
    • View Profile
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: 11032
    • View Profile
    • development blog
    • Email
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/