Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[SFML 2.X] Narzędzie Lasso w programie do edycji grafiki

Ostatnio zmodyfikowano 2025-09-06 17:18
Autor Wiadomość
tBane
Temat założony przez niniejszego użytkownika
» 2025-09-04 16:49:58
Spróbowałem jeszcze raz z ChatemGPT i dał mi rozwiązanie. Wystarczyło domknąć zaznaczenie lasso, by poprawnie renderowało zaznaczenie tzn. teraz już nie ma tego przesunięcia o 1px. No ale toz kolei ogranicza użytkownika w zaznaczaniu kształtu ... Jak sądzicie, zostawić tak ? W Paint'cie to wygląda inaczej - zaznaczenie jest domykane po zakończeniu zaznaczania a nie w trakcie.. To tak jakby ostatniej linii nie chciało rysować :-/

C/C++
#include <iostream>
#include <string>
#include <functional>
#define NOMINMAX
#include <Windows.h>
#include <SFML/Graphics.hpp>

sf::RenderWindow * window;
sf::Vector2i mousePosition;
sf::Vector2f worldMousePosition;

float zoom = 2;
float zoom_delta = 2;
sf::Vector2i canvasSize;
sf::Vector2f canvasPosition;
sf::Sprite canvasSprite;
sf::Color lasso_color = sf::Color( 255, 127, 127, 255 );

sf::Vector2i worldToTile( sf::Vector2f cursorPosition, sf::Vector2f canvasPosition, sf::Vector2i size, float zoom, float zoom_delta ) {
   
float scale = zoom * zoom_delta;
   
sf::Vector2f local = cursorPosition - canvasPosition;
   
int tx = std::clamp( int( std::floor( local.x / scale ) ), 0, size.x - 1 );
   
int ty = std::clamp( int( std::floor( local.y / scale ) ), 0, size.y - 1 );
   
   
//std::cout << "tx = " << tx << ", ty = " << ty << "\n";
   
return sf::Vector2i( tx, ty );
}

sf::Vector2i selectionToTile( sf::Vector2f cursorPosition, sf::Vector2f canvasPosition, sf::Vector2i canvas_size, sf::Vector2i selection_size, sf::Vector2i selection_offset, float zoom, float zoom_delta ) {
   
float scale = zoom * zoom_delta;
   
sf::Vector2f local = cursorPosition - canvasPosition;
   
int tx = std::clamp( int( std::floor( local.x / scale ) ), - selection_size.x + selection_offset.x, canvas_size.x + selection_offset.x );
   
int ty = std::clamp( int( std::floor( local.y / scale ) ), - selection_size.y + selection_offset.y, canvas_size.y + selection_offset.y );
   
   
//std::cout << "tx = " << tx << ", ty = " << ty << "\n";
   
return sf::Vector2i( tx, ty );
}

sf::Vector2i worldToTile( sf::Vector2f cursorPosition, sf::Vector2f canvasPosition, float zoom, float zoom_delta ) {
   
float scale = zoom * zoom_delta;
   
sf::Vector2f local = cursorPosition - canvasPosition;
   
int tx = int( std::floor( local.x / scale ) );
   
int ty = int( std::floor( local.y / scale ) );
   
   
//std::cout << "tx = " << tx << ", ty = " << ty << "\n";
   
return sf::Vector2i( tx, ty );
}

enum class LassoState { None, Selecting, Selected, Moving };

class Lasso {
public:
   
LassoState state;
   
   
std::vector < sf::Vector2i > points;
   
   
//
   
sf::Vector2i offset; // to move
   
    // image
   
sf::Image * image;
   
sf::Texture texture;
   
sf::Sprite sprite;
   
   
// mask
   
sf::RenderTexture mask;
   
sf::Sprite maskSprite;
   
sf::Vector2i maskOffset; // to draw a mask
   
    // outside rect and offset
   
sf::IntRect rect;
   
   
Lasso() {
       
state = LassoState::None;
       
       
points.clear();
       
       
offset = sf::Vector2i( 0, 0 );
       
       
image = nullptr;
       
rect = sf::IntRect( 0, 0, 0, 0 );
       
maskOffset = sf::Vector2i( 0, 0 );
   
}
   
   
~Lasso() { }
   
   
void shiftOriginIfNeeded( sf::Vector2i & point )
   
{
       
sf::Vector2i shift( 0, 0 );
       
if( point.x < 0 ) { shift.x = point.x; point.x = 0; }
       
if( point.y < 0 ) { shift.y = point.y; point.y = 0; }
       
       
if( shift.x != 0 || shift.y != 0 ) {
           
           
maskOffset += shift;
           
           
for( auto & p: points )
               
 p -= shift;
           
       
}
    }
   
   
void addPoint( sf::Vector2i point ) // tile = globalny punkt w kafelkach
   
{
       
point = point - maskOffset;
       
       
shiftOriginIfNeeded( point );
       
       
if( points.empty() || std::hypot( float( points.back().x - point.x ), float( points.back().y - point.y ) ) >= 1.0f )
       
{
           
points.push_back( point );
           
// std::cout << "add point local: " << point.x << ", " << point.y << "\n";
       
}
    }
   
   
void unselect() {
       
points.clear();
       
generateRect();
       
//image = nullptr;
   
}
   
   
void generateRect() {
       
if( points.size() < 3 ) {
           
rect = sf::IntRect( 0, 0, 0, 0 );
           
return;
       
}
       
       
int maxX = std::numeric_limits < int >::lowest();
       
int maxY = std::numeric_limits < int >::lowest();
       
       
for( const auto & p: points ) {
           
maxX = std::max( maxX, p.x );
           
maxY = std::max( maxY, p.y );
       
}
       
       
int w = maxX + 1;
       
int h = maxY + 1;
       
       
rect = sf::IntRect( maskOffset.x, maskOffset.y, w, h );
   
}
   
   
bool clickOnSelection( sf::Vector2i point ) {
       
       
return rect.contains( point );
   
}
   
   
   
   
void generateOutline( float scale ) {
       
if( points.size() < 3 ) return;
       
       
if( rect.width <= 0 || rect.height <= 0 )
           
 return;
       
       
if( mask.getSize() != sf::Vector2u( rect.width, rect.height ) )
           
 mask.create( rect.width, rect.height );
       
       
mask.clear( sf::Color( 127, 47, 47, 127 ) );
       
       
sf::VertexArray lines( sf::LineStrip );
       
       
for( auto & point: points )
           
 lines.append( sf::Vertex( sf::Vector2f( point ), lasso_color ) );
       
       
lines.append( sf::Vertex( sf::Vector2f( points.front() ), lasso_color ) );
       
       
sf::RenderStates rs;
       
rs.blendMode = sf::BlendAlpha;
       
rs.transform.translate( 0.5f, 0.5f );
       
mask.draw( lines, rs );
       
mask.display();
   
}
   
   
void drawOutline( sf::Vector2f canvasPosition, float scale ) {
       
maskSprite = sf::Sprite( mask.getTexture() );
       
maskSprite.setScale( scale, scale );
       
maskSprite.setPosition(
       
canvasPosition + sf::Vector2f( float( rect.left ), float( rect.top ) ) * scale
        );
       
window->draw( maskSprite );
   
}
   
   
   
void draw( sf::Vector2f canvasPosition, float scale ) {
       
       
if( points.size() >= 3 ) {
           
if( true ) { //state == LassoState::Selecting || state == LassoState::Selected) {
               
generateOutline( scale );
               
drawOutline( canvasPosition, scale );
           
}
        }
       
    }
}
;

Lasso * lasso = nullptr;

int main() {
   
   
window = new sf::RenderWindow( sf::VideoMode( 800, 600 ), "test program lasso", sf::Style::Titlebar | sf::Style::Resize | sf::Style::Close );
   
   
canvasSize = sf::Vector2i( 64, 64 );
   
canvasPosition =( sf::Vector2f( window->getSize() ) / 2.0f - sf::Vector2f( canvasSize / 2 ) * zoom * zoom_delta );
   
lasso = new Lasso();
   
   
while( window->isOpen() ) {
       
       
mousePosition = sf::Mouse::getPosition( * window ); // get the mouse position about window
       
worldMousePosition = window->mapPixelToCoords( mousePosition ); // get global mouse position
       
       
       
        // handle events
       
sf::Event event;
       
while( window->pollEvent( event ) ) {
           
           
if( event.type == sf::Event::Closed )
               
 window->close();
           
           
           
if( event.type == sf::Event::MouseButtonReleased && event.mouseButton.button == sf::Mouse::Left ) {
               
if( lasso->state == LassoState::Selecting ) {
                   
lasso->state = LassoState::Selected;
               
}
               
else if( lasso->state == LassoState::Moving ) {
                   
lasso->state = LassoState::Selected;
               
}
            }
           
           
if( event.type == sf::Event::MouseButtonPressed && event.mouseButton.button == sf::Mouse::Left ) {
               
               
sf::Vector2i tile = worldToTile( worldMousePosition, canvasPosition, zoom, zoom_delta );
               
               
if( lasso->clickOnSelection( tile ) ) {
                   
                   
lasso->state = LassoState::Moving;
                   
lasso->offset = tile - lasso->maskOffset;
                   
                   
if( lasso->image == nullptr ) {
                       
lasso->image = new sf::Image();
                       
lasso->generateRect();
                       
lasso->image->create( lasso->rect.width, lasso->rect.height, sf::Color::Transparent );
                       
//copy(lasso->image, &layers_dialog->getCurrentLayer()->image, lasso->rect);
                        //remove(layers_dialog->getCurrentLayer()->image, lasso->rect);
                   
}
                }
               
else if( canvasSprite.getGlobalBounds().contains( worldMousePosition ) ) {
                   
if( lasso->image != nullptr ) {
                       
lasso->generateRect();
                       
//paste(&layers_dialog->getCurrentLayer()->image, lasso->image, lasso->rect.left, lasso->rect.top);
                       
lasso->image = nullptr;
                       
                   
}
                   
                   
                   
lasso->state = LassoState::Selecting;
                   
lasso->unselect();
                   
lasso->maskOffset = tile;
               
}
               
else {
                   
if( lasso->image != nullptr ) {
                       
lasso->generateRect();
                       
//paste(&layers_dialog->getCurrentLayer()->image, lasso->image, lasso->rect.left, lasso->rect.top);
                       
lasso->image = nullptr;
                   
}
                   
                   
lasso->state = LassoState::None;
                   
lasso->unselect();
               
}
            }
        }
       
       
if( sf::Mouse::isButtonPressed( sf::Mouse::Left ) ) {
           
if( lasso->state == LassoState::Moving ) {
               
sf::Vector2i tile = selectionToTile( worldMousePosition, canvasPosition, canvasSize, lasso->rect.getSize(), lasso->offset, zoom, zoom_delta );
               
sf::Vector2i dst = tile - lasso->offset;
               
lasso->maskOffset.x = dst.x;
               
lasso->maskOffset.y = dst.y;
               
lasso->generateRect();
           
}
           
else if( lasso->state == LassoState::Selecting ) {
               
sf::Vector2i tile = worldToTile( worldMousePosition, canvasPosition, canvasSize, zoom, zoom_delta );
               
               
if( lasso->image != nullptr ) {
                   
//paste(&layers_dialog->getCurrentLayer()->image, lasso->image, lasso->rect.left, lasso->rect.top);
                   
lasso->image = nullptr;
               
}
               
               
lasso->addPoint( tile );
               
lasso->generateRect();
               
               
lasso->image = new sf::Image();
               
lasso->image->create( lasso->rect.width, lasso->rect.height, sf::Color::Transparent );
               
//copy(lasso->image, &layers_dialog->getCurrentLayer()->image, lasso->rect);
                //remove(layers_dialog->getCurrentLayer()->image, lasso->rect);
           
}
        }
       
       
// update
       
        // render
       
window->clear( sf::Color( 56, 56, 56 ) );
       
sf::Image empty_image;
       
empty_image.create( canvasSize.x, canvasSize.y, sf::Color( 127, 127, 127 ) );
       
sf::Texture empty_tex = sf::Texture();
       
empty_tex.loadFromImage( empty_image );
       
canvasSprite = sf::Sprite( empty_tex );
       
canvasSprite.setPosition( canvasPosition );
       
canvasSprite.setScale( zoom * zoom_delta, zoom * zoom_delta );
       
window->draw( canvasSprite );
       
       
lasso->draw( canvasPosition, zoom * zoom_delta );
       
       
window->display();
       
       
   
}
   
   
   
return 0;
}
P-182979
DejaVu
» 2025-09-04 17:21:45
Sam jesteś sobie product ownerem więc musisz podjąć decyzję czy użytkownikom, którzy będą korzystali z tego narzędzia będzie obecna postać przeszkadzała czy nie.
P-182980
tBane
Temat założony przez niniejszego użytkownika
» 2025-09-04 17:28:55
Kurde, chciałbym jednak bez tego łączenia :-/ ale nie wiem jak to zrobić :-/ Więc chyba zostawię tak jak jest obecnie :-/
P-182981
tBane
Temat założony przez niniejszego użytkownika
» 2025-09-04 20:42:00
Zlokalizowałem buga. To sf::VertexArray(sf::LineStrip); jest odpowiedzialny za błędne renderowanie ostatniej linii stąd ten brakujący piksel
P-182982
tBane
Temat założony przez niniejszego użytkownika
» 2025-09-05 13:34:18
Problem rozwiązany. Dodałem sf::VertexArray p(sf::Points) dla pierwszego i ostatniego punktu no i te punkty są rysowany na masce :-)


C/C++
#include <iostream>
#include <string>
#include <functional>
#define NOMINMAX
#include <Windows.h>
#include <SFML/Graphics.hpp>

sf::RenderWindow * window;
sf::Vector2i mousePosition;
sf::Vector2f worldMousePosition;

float zoom = 2;
float zoom_delta = 2;
sf::Vector2i canvasSize;
sf::Vector2f canvasPosition;
sf::Sprite canvasSprite;
sf::Color lasso_color = sf::Color( 255, 127, 127, 255 );

sf::Vector2i worldToTile( sf::Vector2f cursorPosition, sf::Vector2f canvasPosition, sf::Vector2i size, float zoom, float zoom_delta ) {
   
float scale = zoom * zoom_delta;
   
sf::Vector2f local = cursorPosition - canvasPosition;
   
int tx = std::clamp( int( std::floor( local.x / scale ) ), 0, size.x - 1 );
   
int ty = std::clamp( int( std::floor( local.y / scale ) ), 0, size.y - 1 );
   
   
//std::cout << "tx = " << tx << ", ty = " << ty << "\n";
   
return sf::Vector2i( tx, ty );
}

sf::Vector2i selectionToTile( sf::Vector2f cursorPosition, sf::Vector2f canvasPosition, sf::Vector2i canvas_size, sf::Vector2i selection_size, sf::Vector2i selection_offset, float zoom, float zoom_delta ) {
   
float scale = zoom * zoom_delta;
   
sf::Vector2f local = cursorPosition - canvasPosition;
   
int tx = std::clamp( int( std::floor( local.x / scale ) ), - selection_size.x + selection_offset.x, canvas_size.x + selection_offset.x );
   
int ty = std::clamp( int( std::floor( local.y / scale ) ), - selection_size.y + selection_offset.y, canvas_size.y + selection_offset.y );
   
   
//std::cout << "tx = " << tx << ", ty = " << ty << "\n";
   
return sf::Vector2i( tx, ty );
}

sf::Vector2i worldToTile( sf::Vector2f cursorPosition, sf::Vector2f canvasPosition, float zoom, float zoom_delta ) {
   
float scale = zoom * zoom_delta;
   
sf::Vector2f local = cursorPosition - canvasPosition;
   
int tx = int( std::floor( local.x / scale ) );
   
int ty = int( std::floor( local.y / scale ) );
   
   
//std::cout << "tx = " << tx << ", ty = " << ty << "\n";
   
return sf::Vector2i( tx, ty );
}

enum class LassoState { None, Selecting, Selected, Moving };

class Lasso {
public:
   
LassoState state;
   
   
std::vector < sf::Vector2i > points;
   
   
//
   
sf::Vector2i offset; // to move
   
    // image
   
sf::Image * image;
   
sf::Texture texture;
   
sf::Sprite sprite;
   
   
// mask
   
sf::RenderTexture mask;
   
sf::Sprite maskSprite;
   
sf::Vector2i maskOffset; // to draw a mask
   
    // outside rect and offset
   
sf::IntRect rect;
   
   
Lasso() {
       
state = LassoState::None;
       
       
points.clear();
       
       
offset = sf::Vector2i( 0, 0 );
       
       
image = nullptr;
       
rect = sf::IntRect( 0, 0, 0, 0 );
       
maskOffset = sf::Vector2i( 0, 0 );
   
}
   
   
~Lasso() { }
   
   
void shiftOriginIfNeeded( sf::Vector2i & point )
   
{
       
sf::Vector2i shift( 0, 0 );
       
if( point.x < 0 ) { shift.x = point.x; point.x = 0; }
       
if( point.y < 0 ) { shift.y = point.y; point.y = 0; }
       
       
if( shift.x != 0 || shift.y != 0 ) {
           
           
maskOffset += shift;
           
           
for( auto & p: points )
               
 p -= shift;
           
       
}
    }
   
   
void addPoint( sf::Vector2i point ) // tile = globalny punkt w kafelkach
   
{
       
point = point - maskOffset;
       
       
shiftOriginIfNeeded( point );
       
       
if( points.empty() || std::hypot( float( points.back().x - point.x ), float( points.back().y - point.y ) ) >= 1.0f )
       
{
           
points.push_back( point );
           
// std::cout << "add point local: " << point.x << ", " << point.y << "\n";
       
}
    }
   
   
void unselect() {
       
points.clear();
       
generateRect();
       
//image = nullptr;
   
}
   
   
void generateRect() {
       
if( points.size() < 3 ) {
           
rect = sf::IntRect( 0, 0, 0, 0 );
           
return;
       
}
       
       
int maxX = std::numeric_limits < int >::lowest();
       
int maxY = std::numeric_limits < int >::lowest();
       
       
for( const auto & p: points ) {
           
maxX = std::max( maxX, p.x );
           
maxY = std::max( maxY, p.y );
       
}
       
       
int w = maxX + 1;
       
int h = maxY + 1;
       
       
rect = sf::IntRect( maskOffset.x, maskOffset.y, w, h );
   
}
   
   
bool clickOnSelection( sf::Vector2i point ) {
       
       
return rect.contains( point );
   
}
   
   
   
   
void generateOutline( bool selectionComplete = false ) {
       
if( points.size() < 3 ) return;
       
       
if( rect.width <= 0 || rect.height <= 0 )
           
 return;
       
       
if( mask.getSize() != sf::Vector2u( rect.width, rect.height ) )
           
 mask.create( rect.width, rect.height );
       
       
mask.clear( sf::Color( 127, 47, 47, 127 ) );
       
       
sf::VertexArray lines( sf::LineStrip );
       
       
for( auto & point: points )
           
 lines.append( sf::Vertex( sf::Vector2f( point ), lasso_color ) );
       
       
// first and last point
       
sf::VertexArray p( sf::Points );
       
p.append( sf::Vertex( sf::Vector2f( points.front() ), lasso_color ) );
       
p.append( sf::Vertex( sf::Vector2f( points.back() ), lasso_color ) );
       
       
if( selectionComplete )
           
 lines.append( sf::Vertex( sf::Vector2f( points.front() ), lasso_color ) );
       
       
sf::RenderStates rs;
       
rs.blendMode = sf::BlendAlpha;
       
rs.transform.translate( 0.5f, 0.5f );
       
mask.draw( lines, rs );
       
mask.draw( p, rs );
       
mask.display();
   
}
   
   
void drawOutline( sf::Vector2f canvasPosition, float scale ) {
       
maskSprite = sf::Sprite( mask.getTexture() );
       
maskSprite.setScale( scale, scale );
       
maskSprite.setPosition(
       
canvasPosition + sf::Vector2f( float( rect.left ), float( rect.top ) ) * scale
        );
       
window->draw( maskSprite );
   
}
   
   
   
void draw( sf::Vector2f canvasPosition, float scale ) {
       
       
if( points.size() >= 3 ) {
           
if( state == LassoState::Selecting ) {
               
generateOutline( false );
               
drawOutline( canvasPosition, scale );
           
}
           
           
if( state == LassoState::Selected || state == LassoState::Moving ) {
               
generateOutline( true );
               
drawOutline( canvasPosition, scale );
           
}
        }
       
    }
}
;

Lasso * lasso = nullptr;

int main() {
   
   
window = new sf::RenderWindow( sf::VideoMode( 800, 600 ), "test program lasso", sf::Style::Titlebar | sf::Style::Resize | sf::Style::Close );
   
   
canvasSize = sf::Vector2i( 64, 64 );
   
canvasPosition =( sf::Vector2f( window->getSize() ) / 2.0f - sf::Vector2f( canvasSize / 2 ) * zoom * zoom_delta );
   
lasso = new Lasso();
   
   
while( window->isOpen() ) {
       
       
mousePosition = sf::Mouse::getPosition( * window ); // get the mouse position about window
       
worldMousePosition = window->mapPixelToCoords( mousePosition ); // get global mouse position
       
       
       
        // handle events
       
sf::Event event;
       
while( window->pollEvent( event ) ) {
           
           
if( event.type == sf::Event::Closed )
               
 window->close();
           
           
           
if( event.type == sf::Event::MouseButtonReleased && event.mouseButton.button == sf::Mouse::Left ) {
               
if( lasso->state == LassoState::Selecting ) {
                   
lasso->state = LassoState::Selected;
               
}
               
else if( lasso->state == LassoState::Moving ) {
                   
lasso->state = LassoState::Selected;
               
}
            }
           
           
if( event.type == sf::Event::MouseButtonPressed && event.mouseButton.button == sf::Mouse::Left ) {
               
               
sf::Vector2i tile = worldToTile( worldMousePosition, canvasPosition, zoom, zoom_delta );
               
               
if( lasso->clickOnSelection( tile ) ) {
                   
                   
lasso->state = LassoState::Moving;
                   
lasso->offset = tile - lasso->maskOffset;
                   
                   
if( lasso->image == nullptr ) {
                       
lasso->image = new sf::Image();
                       
lasso->generateRect();
                       
lasso->image->create( lasso->rect.width, lasso->rect.height, sf::Color::Transparent );
                       
//copy(lasso->image, &layers_dialog->getCurrentLayer()->image, lasso->rect);
                        //remove(layers_dialog->getCurrentLayer()->image, lasso->rect);
                   
}
                }
               
else if( canvasSprite.getGlobalBounds().contains( worldMousePosition ) ) {
                   
if( lasso->image != nullptr ) {
                       
lasso->generateRect();
                       
//paste(&layers_dialog->getCurrentLayer()->image, lasso->image, lasso->rect.left, lasso->rect.top);
                       
lasso->image = nullptr;
                       
                   
}
                   
                   
                   
lasso->state = LassoState::Selecting;
                   
lasso->unselect();
                   
lasso->maskOffset = tile;
               
}
               
else {
                   
if( lasso->image != nullptr ) {
                       
lasso->generateRect();
                       
//paste(&layers_dialog->getCurrentLayer()->image, lasso->image, lasso->rect.left, lasso->rect.top);
                       
lasso->image = nullptr;
                   
}
                   
                   
lasso->state = LassoState::None;
                   
lasso->unselect();
               
}
            }
        }
       
       
if( sf::Mouse::isButtonPressed( sf::Mouse::Left ) ) {
           
if( lasso->state == LassoState::Moving ) {
               
sf::Vector2i tile = selectionToTile( worldMousePosition, canvasPosition, canvasSize, lasso->rect.getSize(), lasso->offset, zoom, zoom_delta );
               
sf::Vector2i dst = tile - lasso->offset;
               
lasso->maskOffset.x = dst.x;
               
lasso->maskOffset.y = dst.y;
               
lasso->generateRect();
           
}
           
else if( lasso->state == LassoState::Selecting ) {
               
sf::Vector2i tile = worldToTile( worldMousePosition, canvasPosition, canvasSize, zoom, zoom_delta );
               
               
if( lasso->image != nullptr ) {
                   
//paste(&layers_dialog->getCurrentLayer()->image, lasso->image, lasso->rect.left, lasso->rect.top);
                   
lasso->image = nullptr;
               
}
               
               
lasso->addPoint( tile );
               
lasso->generateRect();
               
               
lasso->image = new sf::Image();
               
lasso->image->create( lasso->rect.width, lasso->rect.height, sf::Color::Transparent );
               
//copy(lasso->image, &layers_dialog->getCurrentLayer()->image, lasso->rect);
                //remove(layers_dialog->getCurrentLayer()->image, lasso->rect);
           
}
        }
       
       
// update
       
        // render
       
window->clear( sf::Color( 56, 56, 56 ) );
       
sf::Image empty_image;
       
empty_image.create( canvasSize.x, canvasSize.y, sf::Color( 127, 127, 127 ) );
       
sf::Texture empty_tex = sf::Texture();
       
empty_tex.loadFromImage( empty_image );
       
canvasSprite = sf::Sprite( empty_tex );
       
canvasSprite.setPosition( canvasPosition );
       
canvasSprite.setScale( zoom * zoom_delta, zoom * zoom_delta );
       
window->draw( canvasSprite );
       
       
lasso->draw( canvasPosition, zoom * zoom_delta );
       
       
window->display();
       
       
   
}
   
   
   
return 0;
}
P-182983
tBane
Temat założony przez niniejszego użytkownika
» 2025-09-06 17:18:21
Następnie można wygenerować maskę takiego zaznaczenia korzystając z sf::ConvexShape. Poniżej podaję przykład. Temat Wyczerpany :-)

C/C++
sf::RenderTexture * generateMask() {
   
sf::RenderTexture * mask = new sf::RenderTexture();
   
mask->create( image->getSize().x, image->getSize().y );
   
   
std::cout << image->getSize().x << ", " << image->getSize().y << "\n";
   
   
if( points.size() >= 3 ) {
       
mask->clear( sf::Color::Transparent );
       
       
sf::ConvexShape poly;
       
poly.setPointCount( points.size() );
       
for( std::size_t i = 0; i < points.size(); ++i )
           
 poly.setPoint( i, sf::Vector2f( points[ i ] ) );
       
       
poly.setFillColor( sf::Color::White );
       
poly.setOutlineThickness( 0.5f );
       
poly.setOutlineColor( sf::Color::White );
       
       
sf::RenderStates st;
       
st.blendMode = sf::BlendNone;
       
st.transform.translate( 0.5f, 0.5f );
       
mask->draw( poly, st );
   
}
   
else {
       
mask->clear( sf::Color::White );
   
}
   
   
mask->display();
   
mask->setSmooth( false );
   
   
return mask;
}
P-182984
1 2 3 4 « 5 »
Poprzednia strona Strona 5 z 5