Tutorial OpenGL v3.0

Nesse artigo, trago-lhes a biblioteca SFML junto com OpenGL.

[ Hits: 18.782 ]

Por: Thiago Henrique Hüpner em 15/06/2015


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:

#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;
}

Linux: Tutorial OpenGL v3.0
Compile com:

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

Página anterior     Próxima página

Páginas do artigo
   1. Introdução
   2. Primeira integração do OpenGL com o SFML
   3. Brincando com o OpenGL
   4. Simulando uma gambiarra
   5. Simulando uma gambiarra - Parte 2
   6. Agradecimentos, fontes e links úteis
Outros artigos deste autor

Tutorial OpenGL

Tutorial OpenGL v2.0

Ubuntu/Debian/Kali Linux e outros no Android

Visual Studio no Linux

Tutorial SFML

Leitura recomendada

Dynamic libraries com libtool

Algum humor e C++ Design Patterns (parte 2)

OneAPI: A plataforma da Intel para facilitar o desenvolvimento com chips Intel, AMD, ARM, NVIDIA POWER e FPGA

SDL e C - Uma dupla sensacional

Utilizando técnicas recursivas em C e C++

  
Comentários
[1] Comentário enviado por Thihup em 16/06/2015 - 09:17h

Sem comentários? o.0

Acho que já deu de artigos sobre OpenGL, certo?

Se quiserem, ainda tenho mais um artigo pré encaminhado.

[]'s

T+

[2] Comentário enviado por alexsdn em 16/06/2015 - 22:48h

Excelente artigo, de grande valia. Espero que você continue contribuindo do básico ao avançado sobre OpenGL.
Abraço!



Contribuir com comentário