Tutorial OpenGL v3.0
Nesse artigo, trago-lhes a biblioteca SFML junto com OpenGL.
Parte 4: Simulando uma gambiarra
Bom, já simulamos uma gambiarra no SDL, por que não fazer no SFML também?
Esse código ficou um pouco extenso, mas vai dar pra entender tranquilo:
Compile com:
g++ TerceiraJanela.cpp -o TerceiraJanela `pkg-config sfml-all --cflags --libs` -lGL -lGLU
void desenhaNaTela(sf::RectangleShape retangulo, float r = 255, float g = 0, float b = 0) :: Essa função é a função de desenhar, nesse caso, um retângulo, a cor em RGB é opcional, se não for informado, será vermelho, por padrão.
sf::Vector2f posicao = retangulo.getPosition(); :: Cria um vetor 2D de floats que armazenará a posição do retângulo. A posição X é acessada por "posicao.x" e a Y por "posicao.y".
sf::Vector2f tamanho = retangulo.getSize(); :: Cria um vetor 2D de floats que armazenará o tamanho do retângulo. O tamanho "W" (largura) é acessada por "tamanho.x" e o tamanho "H" (altura) é acessada por "tamanho.y".
glColor3ub ( r, g, b ); :: Define a cor do retângulo em RGB, informadas pelos argumentos (padrão é vermelho).
Agora, uma rápida explicação:
Os retângulos possuem 4 pontos: lado superior esquerdo (x,y), lado superior direito (x+w,y), lado inferior direito (x+w,y+h) e lado inferior esquerdo (x,y+w).
Os glVertex2f fazem exatamente isso, desenham o retângulo usando os 4 pontos de um retângulo.
sf::RectangleShape retangulo; :: Cria a variável "retangulo" que contém "um retângulo dentro".
retangulo.setSize(sf::Vector2f(30,30)); :: Define o tamanho do retângulo para 30x30.
retangulo.setPosition((400-30)/2,(400-30)/2); :: Define a posição do retângulo (a conta feita foi apenas para deixar o retângulo centralizado, mas pode ser alterado).
desenhaNaTela(retangulo); :: Desenha o retângulo.
Bom, já sabemos criar retângulos, mas por exemplo, se quissemos criar um círculo seria meio complicado, certo?
Mais ou menos, com essa "gambiarra" que ensinarei agora:
Compile com:
g++ JanelaGambiarra.cpp -o JanelaGambiarra `pkg-config sfml-all --cflags --libs` -lGL -lGLU
O que fazemos no mais é:
(infinitamente...)
Não possui muito segredo, apenas só adicionar 2 comandos principais:
Entre esses 2 podemos utilizar livremente o SFML, mas atenção! Esse método não é muito eficiente, se for necessário, utilize o próprio OpenGL para isso!
sf::CircleShape circulo(40); :: Cria a variável "circulo" com um "circulo" com raio de 40 "floats".
circulo.setFillColor(sf::Color(sf::Color::Black)); :: Define a cor do círculo para preto.
circulo.setPosition(200, 100); :: Define a posição para X: 200 Y: 100.
janela.draw(circulo); :: Desenha o círculo.
Bom, agora vamos para a parte 2 das gambiarras. =D
Esse código ficou um pouco extenso, mas vai dar pra entender tranquilo:
#include <SFML/OpenGL.hpp>
#include <SFML/Graphics.hpp>
void desenhaNaTela(sf::RectangleShape retangulo, float r = 255, float g = 0, float b = 0) {
glLoadIdentity();
// Pega a posicao do Retangulo
sf::Vector2f posicao = retangulo.getPosition();
// Pega o taamanho do retangulo
sf::Vector2f tamanho = retangulo.getSize();
// Define a cor para Vermelho
glColor3ub ( r, g, b );
// Inicia quadrados
glBegin(GL_QUADS);
// Primeira posicao: (x,y)
glVertex2f(posicao.x,posicao.y);
// Segunda posicao: (x+tamanho.x,y)
glVertex2f(posicao.x + tamanho.x, posicao.y);
// Terceira posicao: (x+tamanho.x,y + tamanho.y)
glVertex2f(posicao.x + tamanho.x, posicao.y + tamanho.y);
// Quarta posicao: (x+tamanho.x,y)
glVertex2f(posicao.x, posicao.y + tamanho.y);
glEnd();
}
// Funcao para inicializar o OpenGL
void inicializaOpenGL() {
// Define a Cor de 'limpar' para Branco usando
// Red Blue Green Alpha
glClearColor(255.0f, 255.0f, 255.0f, 1.0f);
// Avisa o OpenGL que qualquer alteração futura
// afetará a Câmera ( O Observador)
glMatrixMode(GL_PROJECTION);
// Reinicia todas as transformações e/ou rotações
glLoadIdentity();
// Define a projeção cartesiana 2D iniciando de (0,0)
// No Lado Superior Esquerdo (ficando igual a projeção do SDL 'puro')
gluOrtho2D(0,400,400,0);
// Avisa o OpenGL que qualquer alteração futura
// afetará o/os desenho/desenhos
glMatrixMode(GL_MODELVIEW);
// 'Limpa' a tela usando a cor de 'limpar' a tela
glClear(GL_COLOR_BUFFER_BIT);
}
int main(void) {
// Cria uma janela de 400x400 com o titulo "Teste com OpenGL"
sf::RenderWindow janela (sf::VideoMode(400,400),"Teste com OpenGL");
// Variavel booleana para indicar se o programa "estaRodando"
bool estaRodando = true;
// Variavel para Eventos
sf::Event evento;
// Inicializa o OpenGL
inicializaOpenGL();
// Main Loop
while(estaRodando) {
// Se existir eventos coloca na variavel
while(janela.pollEvent(evento)) {
// Se foi clicado no 'X' da janela
if(evento.type == sf::Event::Closed) {
// "estaRodando" é falsa
estaRodando = false;
}
}
// Comecar o OpenGL aqui
// Variavel do Retangulo
sf::RectangleShape retangulo;
// Tamanho do Retangulo
retangulo.setSize(sf::Vector2f(30,30));
// Posicao do Retangulo
retangulo.setPosition((400-30)/2,(400-30)/2);
// Desenha na tela o Retangulo
desenhaNaTela(retangulo);
janela.display();
}
janela.close();
return 0;
}
Compile com:
g++ TerceiraJanela.cpp -o TerceiraJanela `pkg-config sfml-all --cflags --libs` -lGL -lGLU
void desenhaNaTela(sf::RectangleShape retangulo, float r = 255, float g = 0, float b = 0) :: Essa função é a função de desenhar, nesse caso, um retângulo, a cor em RGB é opcional, se não for informado, será vermelho, por padrão.
sf::Vector2f posicao = retangulo.getPosition(); :: Cria um vetor 2D de floats que armazenará a posição do retângulo. A posição X é acessada por "posicao.x" e a Y por "posicao.y".
sf::Vector2f tamanho = retangulo.getSize(); :: Cria um vetor 2D de floats que armazenará o tamanho do retângulo. O tamanho "W" (largura) é acessada por "tamanho.x" e o tamanho "H" (altura) é acessada por "tamanho.y".
glColor3ub ( r, g, b ); :: Define a cor do retângulo em RGB, informadas pelos argumentos (padrão é vermelho).
Agora, uma rápida explicação:
Os retângulos possuem 4 pontos: lado superior esquerdo (x,y), lado superior direito (x+w,y), lado inferior direito (x+w,y+h) e lado inferior esquerdo (x,y+w).
Os glVertex2f fazem exatamente isso, desenham o retângulo usando os 4 pontos de um retângulo.
sf::RectangleShape retangulo; :: Cria a variável "retangulo" que contém "um retângulo dentro".
retangulo.setSize(sf::Vector2f(30,30)); :: Define o tamanho do retângulo para 30x30.
retangulo.setPosition((400-30)/2,(400-30)/2); :: Define a posição do retângulo (a conta feita foi apenas para deixar o retângulo centralizado, mas pode ser alterado).
desenhaNaTela(retangulo); :: Desenha o retângulo.
Bom, já sabemos criar retângulos, mas por exemplo, se quissemos criar um círculo seria meio complicado, certo?
Mais ou menos, com essa "gambiarra" que ensinarei agora:
#include <SFML/OpenGL.hpp>
#include <SFML/Graphics.hpp>
void desenhaNaTela(sf::RectangleShape retangulo, float r = 255, int g = 0, int b = 0) {
glLoadIdentity();
// Pega a posicao do Retangulo
sf::Vector2f posicao = retangulo.getPosition();
// Pega o taamanho do retangulo
sf::Vector2f tamanho = retangulo.getSize();
// Define a cor para Vermelho
glColor3ub ( r, g, b );
// Inicia quadrados
glBegin(GL_QUADS);
// Primeira posicao: (x,y)
glVertex2f(posicao.x,posicao.y);
// Segunda posicao: (x+tamanho.x,y)
glVertex2f(posicao.x + tamanho.x, posicao.y);
// Terceira posicao: (x+tamanho.x,y + tamanho.y)
glVertex2f(posicao.x + tamanho.x, posicao.y + tamanho.y);
// Quarta posicao: (x+tamanho.x,y)
glVertex2f(posicao.x, posicao.y + tamanho.y);
glEnd();
}
// Funcao para inicializar o OpenGL
void inicializaOpenGL() {
// Define a Cor de 'limpar' para Branco usando
// Red Blue Green Alpha
glClearColor(255.0f, 255.0f, 255.0f, 1.0f);
// Avisa o OpenGL que qualquer alteração futura
// afetará a Câmera ( O Observador)
glMatrixMode(GL_PROJECTION);
// Reinicia todas as transformações e/ou rotações
glLoadIdentity();
// Define a projeção cartesiana 2D iniciando de (0,0)
// No Lado Superior Esquerdo (ficando igual a projeção do SDL 'puro')
gluOrtho2D(0,400,400,0);
// Avisa o OpenGL que qualquer alteração futura
// afetará o/os desenho/desenhos
glMatrixMode(GL_MODELVIEW);
// 'Limpa' a tela usando a cor de 'limpar' a tela
glClear(GL_COLOR_BUFFER_BIT);
}
int main(void) {
// Cria uma janela de 400x400 com o titulo "Teste com OpenGL"
sf::RenderWindow janela (sf::VideoMode(400,400),"Teste com OpenGL");
// Variavel booleana para indicar se o programa "estaRodando"
bool estaRodando = true;
// Variavel para Eventos
sf::Event evento;
// Inicializa o OpenGL
inicializaOpenGL();
// Main Loop
while(estaRodando) {
// Se existir eventos coloca na variavel
while(janela.pollEvent(evento)) {
// Se foi clicado no 'X' da janela
if(evento.type == sf::Event::Closed) {
// "estaRodando" é falsa
estaRodando = false;
}
}
// Comecar o OpenGL aqui
// Variavel do Retangulo
sf::RectangleShape retangulo;
// Tamanho do Retangulo
retangulo.setSize(sf::Vector2f(30,30));
// Posicao do Retangulo
retangulo.setPosition((400-30)/2,(400-30)/2);
// Desenha na tela o Retangulo
desenhaNaTela(retangulo);
// Salva o estado atual do OpenGL
janela.pushGLStates();
// Aqui estamos "livres" para utilizarcomo quisermos o SFML "puro"
// Cria uma variavel que contém um "circulo" com raio de 40
sf::CircleShape circulo(40);
// Definimos a cor para preta
circulo.setFillColor(sf::Color(sf::Color::Black));
// Definimos a posicao
circulo.setPosition(200, 100);
// Desenhamos a janela
janela.draw(circulo);
// Pegamos o estado anterior da janela
janela.popGLStates();
janela.display();
}
janela.close();
return 0;
}

g++ JanelaGambiarra.cpp -o JanelaGambiarra `pkg-config sfml-all --cflags --libs` -lGL -lGLU
O que fazemos no mais é:
- Desenhar com o OpenGL
- Salvar o estado do OpenGL
- Desenhar com o SFML
- Restaurar o estado do OpenGL
- Desenhar com o OpenGL
(infinitamente...)
Não possui muito segredo, apenas só adicionar 2 comandos principais:
- janela.pushGLStates(); :: Salva o estado atual do OpenGL.
- janela.popGLStates(); :: Volta ao estado salvo.
Entre esses 2 podemos utilizar livremente o SFML, mas atenção! Esse método não é muito eficiente, se for necessário, utilize o próprio OpenGL para isso!
sf::CircleShape circulo(40); :: Cria a variável "circulo" com um "circulo" com raio de 40 "floats".
circulo.setFillColor(sf::Color(sf::Color::Black)); :: Define a cor do círculo para preto.
circulo.setPosition(200, 100); :: Define a posição para X: 200 Y: 100.
janela.draw(circulo); :: Desenha o círculo.
Bom, agora vamos para a parte 2 das gambiarras. =D
Acho que já deu de artigos sobre OpenGL, certo?
Se quiserem, ainda tenho mais um artigo pré encaminhado.
[]'s
T+