Futuramente pretendo trazer mais conteúdos sobre OpenGL e Vulkan, no entanto, uma das melhores ferramentas para se “preparar” para essas próximas realidades é o SFML.
Aliás, SFML também é interessante para entrar no mundo do desenvolvimento de games e gráficos, além de você passar a entender melhor outras bibliotecas, tais como: SDL2, Raylib, Allegro, além de facilitar também o aprendizado de motores gráficos como: Godot, Unity e entre outros.
E uma das ferramentas interessantes do SFML, para usar, é a sf::Vertex
.
sf::Vertex
é uma classe (ou mais precisamente, uma struct
) do SFML que representa um único vértice no espaço 2D e armazena informações como:
Inciando do zero para entender como funciona de verdade o sf::Vertex
.
draw
é necessário passar 3 parâmetros, além do &vertex
como referência, pois ele não é drawable....
sf::Vertex vertex;
...
window.draw(&vertex, 1, sf::Points);
...
Note que usamos o modelo: sf::Points
, ele só desenha um único ponto. Existem outros modelos, veremos mais à frente.
Ele está aparecendo na tela, no entanto, na posição:
0, 0
, ou seja, você não conseguirá notar.
.position
, exemplo:vertex.position = sf::Vector2f(100.f, 100.f);
Note que aparecerá um pontinho(1 único vértice) branco na tela!
Esse exemplo básico poderia ser substituído usando somente o construtor:
sf::Vertex vertex(sf::Vector2f(100.f, 100.f));
.color
vertex.color = sf::Color::Red;
// Ou diretamente no construtor:
sf::Vertex vertex(sf::Vector2f(100.f, 100.f), sf::Color::Red);
.texCoords
.
Como o próprio nome sugere, ela é usada para definir coordenadas para uma possível textura que você queira “encaixar” ao seu vertex. Além de poder passá-la diretamente no construtor, você também pode definir posteriormente:
vertex.textCoords = sf::Vector2f(0.f, 0.f);
Desenhar só um vértice pode até ter alguma utilidade, dependendo do que você está fazendo, mas geralmente não há utilidade na maioria dos casos. No próximo tópico veremos como usar múltiplos vertex(s).
A forma correta de usar vertex é em conjunto. Nesse exemplo vamos posicionar um em cada ponto de um possível quadrado:
sf::Vertex vertex[4] = {
sf::Vertex(sf::Vector2f(100.f, 100.f), sf::Vector2f(0.f, 0.f)), // Top-left
sf::Vertex(sf::Vector2f(200.f, 100.f), sf::Vector2f(100.f, 0.f)), // Top-right
sf::Vertex(sf::Vector2f(200.f, 200.f), sf::Vector2f(100.f, 100.f)), // Bottom-right
sf::Vertex(sf::Vector2f(100.f, 200.f), sf::Vector2f(0.f, 100.f)) // Bottom-left
};
E agora, como não é um único e sim 4 vertex, nao usamos mais referência para desenhar:
window.draw(vertex, 4, sf::Points);
Vai renderizar assim:
sf::Vertex
Nós usamos e falamos sobre o sf::Points
, logicamente, ele só desenha pontos, mas existem outros. São eles:
sf::Lines
, ele liga os pontos que estão na mesma linha:sf::LineStrip
, similar ao sf::Lines
, mas ele faz uma ligação a mais em uma das verticais:sf::Quads
, ele preenche(fill) o conteúdo tomando os vértices como coordenada:sf::Triangles
, similar ao sf::Quads
, mas é para triângulos, lógico que seu array precisa ter 3 elementos agora: sf::Vertex vertex[3]
:sf::TriangleStrip
, voltamos para os 4 elementos para o array, e note que ele preenche, menos um formato de triângulo:sf::TriangleFan
, termina no mesmo vértice que inicio gerando um efeito similar ao sf::Quads
com fill:
Agora tem um vertex com 5 vértices:
...
sf::Vertex vertex[5] = {
sf::Vertex(sf::Vector2f(150, 150)), // início
sf::Vertex(sf::Vector2f(100, 100)),
sf::Vertex(sf::Vector2f(150, 100)),
sf::Vertex(sf::Vector2f(200, 100)),
sf::Vertex(sf::Vector2f(150, 150)) // final
};
...
window.draw(vertex, 5, sf::TriangleFan);
...
...
sf::Vertex vertex[3] = {
sf::Vertex(sf::Vector2f(400.f, 100.f), sf::Color::Red), // Topo (vermelho)
sf::Vertex(sf::Vector2f(300.f, 300.f), sf::Color::Green), // Esquerda (verde)
sf::Vertex(sf::Vector2f(500.f, 300.f), sf::Color::Blue) // Direita (azul)
};
...
window.clear(sf::Color::White);
window.draw(vertex, 3, sf::Triangles);
...
#include <SFML/Graphics.hpp>
int main() {
sf::RenderWindow window(
sf::VideoMode(800, 450),
"C++ sf::Vertex",
sf::Style::Titlebar | sf::Style::Close
);
sf::Vertex cPlusPlus[15];
// "C"
cPlusPlus[0] = sf::Vertex(sf::Vector2f(100.f, 200.f), sf::Color::Blue); // Superior esquerdo
cPlusPlus[1] = sf::Vertex(sf::Vector2f(200.f, 200.f), sf::Color::White); // Superior direito
cPlusPlus[2] = sf::Vertex(sf::Vector2f(200.f, 250.f), sf::Color::Blue); // Inferior direito
cPlusPlus[3] = sf::Vertex(sf::Vector2f(150.f, 250.f), sf::Color::White); // Meio
cPlusPlus[4] = sf::Vertex(sf::Vector2f(150.f, 300.f), sf::Color::Blue); // Inferior direito
cPlusPlus[5] = sf::Vertex(sf::Vector2f(100.f, 300.f), sf::Color::White); // Inferior esquerdo
cPlusPlus[6] = sf::Vertex(sf::Vector2f(100.f, 200.f), sf::Color::Blue); // Fechando o C
// 1º "+"
cPlusPlus[7] = sf::Vertex(sf::Vector2f(250.f, 225.f), sf::Color::Blue); // Meio esquerdo
cPlusPlus[8] = sf::Vertex(sf::Vector2f(350.f, 225.f), sf::Color::White); // Meio direito
cPlusPlus[9] = sf::Vertex(sf::Vector2f(300.f, 175.f), sf::Color::Blue); // Superior
cPlusPlus[10] = sf::Vertex(sf::Vector2f(300.f, 275.f), sf::Color::White); // Inferior
// 2º "+"
cPlusPlus[11] = sf::Vertex(sf::Vector2f(400.f, 225.f), sf::Color::Blue); // Meio esquerdo
cPlusPlus[12] = sf::Vertex(sf::Vector2f(500.f, 225.f), sf::Color::White); // Meio direito
cPlusPlus[13] = sf::Vertex(sf::Vector2f(450.f, 175.f), sf::Color::Blue); // Superior
cPlusPlus[14] = sf::Vertex(sf::Vector2f(450.f, 275.f), sf::Color::White); // Inferior
while (window.isOpen()) {
sf::Event event;
while (window.pollEvent(event)) {
if (event.type == sf::Event::Closed)
window.close();
}
window.clear(sf::Color::Black);
window.draw(cPlusPlus, 7, sf::TriangleFan);
window.draw(&cPlusPlus[7], 4, sf::Lines);
window.draw(&cPlusPlus[11], 4, sf::Lines);
window.display();
}
return 0;
}
Existe um outro tipo também muito usado que é o sf::VertexArray
, ele facilita o uso e a implementação, sem dizer que é drawable, exemplo:
...
sf::VertexArray lines(sf::LinesStrip, 5);
lines[0].position = sf::Vector2f(100.f, 100.f);
lines[1].position = sf::Vector2f(200.f, 100.f);
lines[2].position = sf::Vector2f(200.f, 200.f);
lines[3].position = sf::Vector2f(100.f, 200.f);
lines[4].position = sf::Vector2f(100.f, 100.f);
...
window.draw(lines);
...
Isso renderiza um quadrado de linhas sem fill. Nesse vídeo criamos um fundo gradiente com
sf::VertexArray
.
Para mais informações acesse: https://www.sfml-dev.org/tutorials/2.5/graphics-vertex-array.php.