Tutorial OpenGL v3.0

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

[ Hits: 17.237 ]

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

Ubuntu/Debian/Kali Linux e outros no Android

Tutorial SFML

Visual Studio no Linux

Tutorial OpenGL v2.0

Tutorial OpenGL

Leitura recomendada

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

SDL - Ótimo para criação de jogos

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

Bug afeta todas as distros

A duplicação do buffer de saída na chamada de sistema fork() do Linux

  
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




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts