Ostatnio zmodyfikowano wczoraj o godz. 22:26
tBane Temat założony przez niniejszego użytkownika |
RGB i HUE - operacje na palecie kolorów » 2025-11-10 18:46:26 Witam. Posiadam kod na generowanie palety kolorów, który zamieszczam poniżej. Moje pytanie brzmi jak wyznaczyć funkcję odwrotną do RGB->HUE w taki sposób, by zwrócić koordynaty danego piksela. chodzi o to że jak podamy wartość np. 255, 0, 0 to zwróci nam 0,0.  Czy da się to obliczyć czy lepiej zastosować spradzenie dla każdego piksela ? kod:std::string palette_colors_shader_source = R"(
uniform sampler2D texture; // SFML podstawi teksturę sprite'a
uniform vec4 texRectUV; // (u0, v0, u1, v1) – NORMALIZOWANE granice wycinka
// --- HSV -> RGB (oficjalne) ---
vec3 hsv2rgb(in vec3 c) {
vec3 rgb = clamp(abs(mod(c.x*6.0 + vec3(0.0,4.0,2.0), 6.0) - 3.0) - 1.0, 0.0, 1.0);
return c.z * mix(vec3(1.0), rgb, c.y);
}
// --- HSV -> RGB (wygładzone) ---
vec3 hsv2rgb_smooth(in vec3 c) {
vec3 rgb = clamp(abs(mod(c.x*6.0 + vec3(0.0,4.0,2.0), 6.0) - 3.0) - 1.0, 0.0, 1.0);
rgb = rgb * rgb * (3.0 - 2.0 * rgb);
return c.z * mix(vec3(1.0), rgb, c.y);
}
void main() {
vec2 uvAtlas = gl_TexCoord[0].xy;
vec2 uv = (uvAtlas - texRectUV.xy) / (texRectUV.zw - texRectUV.xy);
float hue = fract(uv.x);
vec3 hsv = vec3(hue, 1.2 - uv.y, 1.3);
vec3 hsvRgb = hsv2rgb_smooth(hsv);
gl_FragColor = vec4(hsvRgb, 1.0);
}
)";
#include "Dialogs/Palette.hpp" #include "Filters.hpp" #include "Time.hpp" #include "Window.hpp" #include "Cursor.hpp" #include "Tools/Toolbar.hpp" #include "SFML/Graphics.hpp" #include "Theme.hpp"
PaletteValues::PaletteValues( sf::Vector2i position, sf::Vector2i size, std::string shader, sf::Color color ) { _shader = sf::Shader(); _shader.loadFromMemory( shader, sf::Shader::Type::Fragment ); _rect = sf::IntRect( position, size ); loadTexture( color ); _state = PaletteState::None; }
PaletteValues::~PaletteValues() { }
void PaletteValues::loadTexture( sf::Color color ) { sf::Image img; img.resize( sf::Vector2u( _rect.size ), color ); sf::Texture tex; tex.loadFromImage( img ); sf::IntRect r = sf::IntRect( sf::Vector2i( 0, 0 ), sf::Vector2i( tex.getSize().x, tex.getSize().y ) ); sf::Vector2u ts = tex.getSize(); sf::Glsl::Vec4 texRectUV( float( r.position.x ) / ts.x, float( r.position.y ) / ts.y, float( r.position.x + r.size.x ) / ts.x, float( r.position.y + r.size.y ) / ts.y ); _shader.setUniform( "texRectUV", texRectUV ); _renderTexture.resize( tex.getSize() ); sf::Sprite spr( tex ); _renderTexture.clear( sf::Color::White ); _renderTexture.draw( spr, & _shader ); _renderTexture.display(); }
void PaletteValues::setPosition( sf::Vector2i position ) { _rect.position = position; }
void PaletteValues::cursorHover() { if( _rect.contains( cursor->_worldMousePosition ) ) { ElementGUI_hovered = this->shared_from_this(); } }
void PaletteValues::handleEvent( const sf::Event & event ) { if( const auto * mbr = event.getIf < sf::Event::MouseButtonReleased >(); mbr && mbr->button == sf::Mouse::Button::Left ) { _state = PaletteState::None; ElementGUI_pressed = nullptr; } if( _rect.contains( cursor->_worldMousePosition ) ) { if( const auto * mbp = event.getIf < sf::Event::MouseButtonPressed >(); mbp && mbp->button == sf::Mouse::Button::Left ) { _state = PaletteState::Selecting; ElementGUI_pressed = this->shared_from_this(); } if( const auto * mbp = event.getIf < sf::Event::MouseMoved >(); mbp && sf::Mouse::isButtonPressed( sf::Mouse::Button::Left ) ) { _state = PaletteState::Selecting; ElementGUI_pressed = this->shared_from_this(); } } }
void PaletteValues::update() { if( _state == PaletteState::Selecting ) { _state = PaletteState::Selecting; sf::Image pixels = _renderTexture.getTexture().copyToImage(); sf::Vector2i pixelPos; pixelPos.x = std::clamp( cursor->_worldMousePosition.x - _rect.position.x, 0, _rect.size.x - 1 ); pixelPos.y = std::clamp( cursor->_worldMousePosition.y - _rect.position.y, 0, _rect.size.y - 1 ); sf::Color color = pixels.getPixel( sf::Vector2u( pixelPos ) ); toolbar->_selectedColorButton->setColor( color ); } }
void PaletteValues::draw() { sf::Sprite sprite( _renderTexture.getTexture() ); sprite.setPosition( sf::Vector2f( _rect.position ) ); window->draw( sprite ); }
Palette::Palette() : Dialog( L"Palette", sf::Vector2i( 192 + 24 + 8, dialog_title_rect_height + 192 + basic_text_rect_height + 8 ) ) { sf::Vector2i size = sf::Vector2i( sf::Vector2u( sf::Vector2i( 192 - 16, 192 - 16 ) ) ); sf::Vector2i position = getContentPosition() + sf::Vector2i( 8, 8 ); _hues = std::make_shared < PaletteValues >( position, size, palette_colors_shader_source, sf::Color::White ); position = sf::Vector2i( _hues->_rect.position + sf::Vector2i( _hues->_rect.size.x + 8, 0 ) ); size.x = 24; _values = std::make_shared < PaletteValues >( position, size, palette_values_shader_source, sf::Color::White ); _r = std::make_unique < sf::Text >( basicFont, L"R", basic_text_size ); _g = std::make_unique < sf::Text >( basicFont, L"G", basic_text_size ); _b = std::make_unique < sf::Text >( basicFont, L"B", basic_text_size ); _r->setFillColor( basic_text_color ); _g->setFillColor( basic_text_color ); _b->setFillColor( basic_text_color ); _red = std::make_shared < TextInput >( sf::Vector2i( 32, basic_text_rect_height ), 3, basic_text_size ); _green = std::make_shared < TextInput >( sf::Vector2i( 32, basic_text_rect_height ), 3, basic_text_size ); _blue = std::make_shared < TextInput >( sf::Vector2i( 32, basic_text_rect_height ), 3, basic_text_size ); setPosition( _position ); }
Palette::~Palette() { }
void Palette::setPosition( sf::Vector2i position ) { Dialog::setPosition( position ); _hues->setPosition( getContentPosition() + sf::Vector2i( 8, 8 ) ); _values->setPosition( sf::Vector2i( _hues->_rect.position + sf::Vector2i( _hues->_rect.size.x + 8, 0 ) ) ); sf::Vector2i textInputsPosistion; textInputsPosistion.x = position.x + 32; textInputsPosistion.y = _values->_rect.position.y + _values->_rect.size.y + 8; _red->setPosition( textInputsPosistion ); _green->setPosition( textInputsPosistion + sf::Vector2i( 32 * 2, 0 ) ); _blue->setPosition( textInputsPosistion + sf::Vector2i( 32 * 4, 0 ) ); _r->setPosition( sf::Vector2f( _red->getPosition() ) - sf::Vector2f( 16, 0 ) ); _g->setPosition( sf::Vector2f( _green->getPosition() ) - sf::Vector2f( 16, 0 ) ); _b->setPosition( sf::Vector2f( _blue->getPosition() ) - sf::Vector2f( 16, 0 ) ); }
void Palette::cursorHover() { Dialog::cursorHover(); _hues->cursorHover(); _values->cursorHover(); _red->cursorHover(); _green->cursorHover(); _blue->cursorHover(); }
void Palette::handleEvent( const sf::Event & event ) { Dialog::handleEvent( event ); _hues->handleEvent( event ); _values->handleEvent( event ); _red->handleEvent( event ); _green->handleEvent( event ); _blue->handleEvent( event ); }
void Palette::update() { Dialog::update(); _hues->update(); if( _hues->_state == PaletteState::Selecting ) { _values->loadTexture( toolbar->_selectedColorButton->_color ); } _values->update(); _red->update(); _green->update(); _blue->update(); }
void Palette::draw() { Dialog::draw(); _hues->draw(); _values->draw(); _red->draw(); _green->draw(); _blue->draw(); window->draw( * _r ); window->draw( * _g ); window->draw( * _b ); }
std::shared_ptr < Palette > palette;
|
|
pekfos |
» 2025-11-10 18:56:52 |
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-11-10 20:08:05 Ok. dzięki, zobacze może się przyda :-) Bo ChatGPT jakoś zaczął działać, a szczerze mówiąc jestem na etapie na którym nie rozumiem już kodu ... |
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-11-10 21:00:59 struct HSV { float h, s, v; }; HSV rgbToHsv( sf::Color c ) { float r = c.r / 255.f, g = c.g / 255.f, b = c.b / 255.f; float mx = std::max( { r, g, b } ), mn = std::min( { r, g, b } ); float d = mx - mn; float h = 0.f; if( d > 0.f ) { if( mx == r ) h = fmodf(( g - b ) / d, 6.f ); else if( mx == g ) h =( b - r ) / d + 2.f; else h =( r - g ) / d + 4.f; h /= 6.f; if( h < 0.f ) h += 1.f; } float s =( mx == 0.f ) ? 0.f :( d / mx ); float v = mx; return { h, s, v }; }
sf::Vector2i cursorOnHues( const sf::IntRect & rectHues, sf::Color rgb ) { HSV hsv = rgbToHsv( rgb ); float x = std::clamp( hsv.h, 0.f, 1.f ); float y = std::clamp( 1.0f - hsv.s, 0.f, 1.f ); return sf::Vector2i( rectHues.position.x + x * rectHues.size.x, rectHues.position.y + y * rectHues.size.y ); }
|
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-11-10 21:27:24 Ten shader nie generuje poprawnie palety kolorów. Nie działają wartości skrajne takie jak: 255,0,0 255,255,255 0,0,0
Jak myślicie poprawić to czy zostawić tak jak jest? |
|
skovv |
» 2025-11-10 21:29:42 A nie łatwiej Ci zamiast shadera to wygenerować sobie samemu palete na texturze? A jak chcesz wtedy znaleźć pozycje danego koloru to szukasz na texturze i od razu masz pozycje |
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-11-10 22:26:52 No właśnie generuje teksturę ale z użyciem shadera. A obliczanie koloru jest po to, bo nie każdy kolor jest na palecie. Paleta nie przechowuje wszystkich kolorów tylko te które widać, dlatego stosuje obliczanie. |
|
| « 1 » |