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

[SFML 2.X] sf::VertexArray(sf::Lines) - Pogrubienie linii

Ostatnio zmodyfikowano 2025-04-03 23:26
Autor Wiadomość
tBane
Temat założony przez niniejszego użytkownika
[SFML 2.X] sf::VertexArray(sf::Lines) - Pogrubienie linii
» 2025-04-03 21:20:11
Witam. Potrzebuję pogrubić renderowaną linię, ale niestety SFML tego nie wspira. Stąd pomysł, by napisać shader. Ale nie wiem za bardzo jak to zrobić.



C/C++
void draw( sf::Vector2f position = sf::Vector2f( 0, 0 ) ) {
   
sf::VertexArray msh( sf::Lines );
   
   
for( auto & tri: triangles ) {
       
       
msh.append( sf::Vertex( sf::Vector2f( tri.a.x + position.x, tri.a.y + position.y ), sf::Color::Red ) );
       
msh.append( sf::Vertex( sf::Vector2f( tri.b.x + position.x, tri.b.y + position.y ), sf::Color::Red ) );
       
       
msh.append( sf::Vertex( sf::Vector2f( tri.b.x + position.x, tri.b.y + position.y ), sf::Color::Red ) );
       
msh.append( sf::Vertex( sf::Vector2f( tri.c.x + position.x, tri.c.y + position.y ), sf::Color::Red ) );
       
       
msh.append( sf::Vertex( sf::Vector2f( tri.c.x + position.x, tri.c.y + position.y ), sf::Color::Red ) );
       
msh.append( sf::Vertex( sf::Vector2f( tri.a.x + position.x, tri.a.y + position.y ), sf::Color::Red ) );
       
   
}
   
   
//sf::RenderStates rstate;
    //rstate.shader = getShader("line_shader");
    //window->draw(msh, rstate);
   
   
window->draw( msh );
   
}
P-182191
DejaVu
» 2025-04-03 21:24:20
ChatGPT 4o:
Aby pogrubić linie renderowane za pomocą SFML 2.x, można zastosować kilka podejść:

### 1. Rysowanie wielokątów zamiast linii

SFML nie obsługuje bezpośrednio grubych linii. Możesz jednak symulować grube linie, rysując prostokąty lub inne wielokąty o żądanej grubości. Dla każdego odcinka linii oblicz jego wektor normalny, a następnie użyj go do utworzenia prostokąta reprezentującego grubą linię.

**Przykład:**


C/C++
void drawThickLine( sf::RenderWindow & window, sf::Vector2f start, sf::Vector2f end, float thickness, sf::Color color ) {
   
sf::Vector2f direction = end - start;
   
sf::Vector2f unitDirection = direction / std::sqrt( direction.x * direction.x + direction.y * direction.y );
   
sf::Vector2f normal( - unitDirection.y, unitDirection.x );
   
sf::Vector2f offset =( thickness / 2.f ) * normal;
   
   
sf::Vertex vertices[ 4 ];
   
vertices[ 0 ].position = start + offset;
   
vertices[ 1 ].position = end + offset;
   
vertices[ 2 ].position = end - offset;
   
vertices[ 3 ].position = start - offset;
   
   
for( int i = 0; i < 4; ++i ) {
       
vertices[ i ].color = color;
   
}
   
   
window.draw( vertices, 4, sf::Quads );
}


Powyższa funkcja rysuje grubą linię jako czworokąt między punktami `start` i `end` o zadanej grubości.

### 2. Użycie shadera

Innym podejściem jest zastosowanie shadera do manipulacji szerokością linii podczas renderowania. SFML obsługuje shadery, co pozwala na modyfikację wyglądu obiektów na poziomie GPU. Należy jednak pamiętać, że użycie shaderów może być bardziej skomplikowane i wymagać dodatkowej wiedzy na temat GLSL.

**Przykład shadera w GLSL:**



uniform float thickness;
uniform vec2 resolution;

void main() {
    vec2 pos = gl_FragCoord.xy / resolution;
    // Implementacja logiki pogrubienia linii
}


Następnie w kodzie C++ należy załadować shader i ustawić odpowiednie uniformy:


C/C++
sf::Shader shader;
if( !shader.loadFromFile( "line_shader.frag", sf::Shader::Fragment ) ) {
   
// Obsługa błędu
}
shader.setUniform( "thickness", desiredThickness );
shader.setUniform( "resolution", sf::Vector2f( window.getSize() ) );


Należy jednak pamiętać, że implementacja takiego shadera może być skomplikowana i wymagać dostosowania do konkretnych potrzeb aplikacji.

### 3. Użycie biblioteki zewnętrznej

Istnieją również biblioteki zewnętrzne, takie jak [Thor](http://bromeon.ch/libraries/thor/), które rozszerzają funkcjonalność SFML i oferują gotowe rozwiązania do rysowania grubych linii oraz innych kształtów. Korzystanie z takich bibliotek może znacznie ułatwić implementację.

**Przykład użycia biblioteki Thor:**


C/C++
#include <Thor/Shapes/ConcaveShape.hpp>

thor::ConcaveShape thickLine;
thickLine.setPointCount( 4 );
thickLine.setPoint( 0, start + offset );
thickLine.setPoint( 1, end + offset );
thickLine.setPoint( 2, end - offset );
thickLine.setPoint( 3, start - offset );
thickLine.setFillColor( color );

window.draw( thickLine );


Wybór odpowiedniego podejścia zależy od specyfiki projektu oraz preferencji programisty.
P-182192
tBane
Temat założony przez niniejszego użytkownika
» 2025-04-03 21:34:08
Ok, dziękuję :-)
P-182193
DejaVu
» 2025-04-03 22:35:00
a działa?
P-182194
tBane
Temat założony przez niniejszego użytkownika
» 2025-04-03 23:26:30
Tak, działa :-) Na screenach najpierw mesh rysowany grubszą linią a na mapie cieńszą


P-182195
« 1 »
  Strona 1 z 1