Pular para o conteúdo

Tutorial OpenGL

Tutorial básico de OpenGL com exemplos práticos.
Thiago Henrique Hüpner Thihup
Hits: 71.719 Categoria: C/C++ Subcategoria: Miscelânea
  • Indicar
  • Impressora
  • Denunciar

Parte 3: Manipulação de eventos do teclado e mouse

Após entendermos como desenha na tela, agora vamos pular para "outro nível", nós iremos usar o teclado e o mouse para testar.

O código é grande, mas vocês irão entender o conceito.
  • A seta direcional para cima aumenta a velocidade de rotação. Para baixo, diminui.
  • Se a seta para o lado esquerdo/direito for apertada, o quadrado muda de direção.
  • A barra de espaço altera o tipo de rotação.
  • O F11 deixa em tela cheia.
  • O Esc fecha a janela, detecta o movimento do mouse, e com o clique (em cima da tela) é impresso a localização, e se clicar também.

Para início de conversa, compilem esse código:

#include <GL/glut.h>
#include <stdio.h>

float angulo = 0.0f,rotX = 1.0,rotY = 0.0f,rotZ = 0.0f,velocidade = 1.00;

void DesenhaNaTela(void)
{
    // Clear Color and Depth Buffers
    glClear(GL_COLOR_BUFFER_BIT);

    // Reset transformations
    glLoadIdentity();

    gluLookAt(  0.0f, 0.0f, 10.0f,
                        0.0f, 0.0f,  0.0f,
                        0.0f, 1.0f,  0.0f);

    glRotatef(angulo, rotX, rotY, rotZ);

    // Está colorido, caso queiram apenas uma cor, comente todos os glColor3f e descomente aqui
    // glColor3f(0.0, 0.5, 0.9);


        glBegin(GL_QUADS);
        glColor3f(1,0,0);
        glColor3f(1,0,0);
        glVertex3f(-1, 1, 0);
       glColor3f(1,1,0);
        glVertex3f( 1, 1, 0);
       glColor3f(0,1,0);
        glVertex3f( 1,-1, 0);
        glColor3f(0,0,1);
        glVertex3f(-1,-1, 0);
        glEnd();

    angulo+=velocidade;

    glutSwapBuffers();
}

void Inicializa (void)
{
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Define cor fundo para preto
}

void Teclado(unsigned char key, int x, int y){
    if(key == 27) exit(0); // O Programa Fecha Caso o Esc seja apertado ...

    if((char)key == ' '){
        if(rotX == 1.0f){
        rotX = 0.0f;
        rotY = 1.0f;
        rotZ = 0.0f;
        }else if (rotY == 1.0f){
        rotX = 0.0f;
        rotY = 0.0f;
        rotZ = 1.0f;
        }else if(rotZ == 1.0f){
        rotX = 1.0f;
        rotY = 0.0f;
        rotZ = 0.0f;
        }

    }

}

void TeclaEspeciais(int key, int x, int y){

    if(key == GLUT_KEY_UP) {
    velocidade += 0.05;
    printf("Velocidade Rotação : %.2f\n",velocidade);
    }
    if(key == GLUT_KEY_DOWN) {
    velocidade -=  0.05;
    printf("Velocidade Rotação : %.2f\n",velocidade);
    }

    if(key == GLUT_KEY_LEFT)
        if(velocidade < 0)velocidade *= -1;
    if(key == GLUT_KEY_RIGHT)
        if(velocidade > 0)velocidade *= -1;
}

void CliqueMouse(int button, int state, int x, int y){

    if(button == GLUT_LEFT_BUTTON){
        if(state == GLUT_DOWN){
        printf("Clicou com o botão esquerdo na Posição  X : %i Y : %i \n",x,y);
        }else if (state == GLUT_UP){
        printf("Soltou Botão esquerdo\n");
        }
    }else if(button == GLUT_RIGHT_BUTTON){
        if(state == GLUT_DOWN){
        printf("Clicou com o botão direito na Posição  X : %i Y : %i \n",x,y);
        }else if(state == GLUT_UP){
        printf("Soltou Botão direito\n");
        }
    }else if (button == GLUT_MIDDLE_BUTTON){
        if(state == GLUT_DOWN){
        printf("Clicou com o botão do meio na Posição  X : %i Y : %i \n",x,y);
        }else if(state == GLUT_UP){
        printf("Soltou Botão do meio\n");
        }
    }
}

void MovimentoMouse (int x,int y) {

    printf("Mouse na Posição  X : %i Y : %i \n",x,y);

}

void AlteraTamanhoTela(int w, int h) {

// Função é chamada caso a tela tenha tido alterada

    if (h == 0)
        h = 1;

    float proporcao =  w * 1.0 / h;

    glMatrixMode(GL_PROJECTION);

    glLoadIdentity();

    glViewport(0, 0, w, h);

    gluPerspective(45.0f, proporcao, 0.1f, 100.0f);

    glMatrixMode(GL_MODELVIEW);
}

int main(int argc, char** argv)
{
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    glutInitWindowSize(320,240);
    glutInitWindowPosition(100,100);
    glutCreateWindow("Manipulação Teclado e Mouse");
    glutDisplayFunc(DesenhaNaTela);
    glutIdleFunc(DesenhaNaTela);
    glutReshapeFunc(AlteraTamanhoTela);
    glutMouseFunc(CliqueMouse);
    glutPassiveMotionFunc(MovimentoMouse);
    glutKeyboardFunc( Teclado );
    glutSpecialFunc( TeclaEspeciais);
    Inicializa();
    glutMainLoop();
}

glLoadIdentity :: reseta todas as transformações e/ou rotações.

gluLookAt :: esse, talvez, seja o maior "medo" de vocês, essa função define onde a câmera será posicionada:

glRotatef :: rotaciona a objeto (nesse caso, o quadrado) em determinada posição (obs.: eu coloquei aqui sem números, pois defini as variáveis e elas irão me ajudar a rotacionar de modo "legal").

Olhem como o OpenGL consegue "misturar" as cores.

Teclado:
  • Se o Esc for pressionado, o programa é encerrado. Aqui, eu usei ((char)key) para não ter que trabalhar com os números da tabela ASCII.
  • Se o espaço (" ") for pressionado, ele verifica para qual posição alterar.

TeclaEspeciais:
  • Se a seta direcional para cima for apertada, a velocidade aumenta.
  • Se a seta direcional para baixo for apertada, a velocidade diminui.
  • Se a seta para o lado for apertada o quadrado muda de direção.

CliqueMouse:
  • Se o botão do mouse for igual ao botão esquerdo, e ele estiver pressionado, imprimirá a posição aonde foi clicado, se for solto, mostrará que foi solto.

Os outros seguem a mesma regra:

MovimentoMouse:
  • Esse mostra aonde o mouse passou (a posição).

AlteraTamanhoTela:
  • Essa talvez é a mais assustadora: caso o tamanho da tela seja alterado, essa função é chamada.

Se a altura for igual a zero, o tamanho fica igual a 1.
A proporção (proporção da tela) é igual a largura * 1 / pela altura.

glViewport; :: seus parâmetros especificam o canto inferior esquerdo da viewport (x,y) dentro da janela, e a sua largura e altura em pixels (width e height). Em outras palavras, a viewport define a área dentro janela, em coordenadas de tela, que OpenGL pode usar para fazer o desenho.

gluPerspective; :: esta função estabelece os parâmetros da Projeção Perspectiva, atualizando a matriz de projeção perspectiva.

Main:
  • glutInitDisplayMode : GLUT_DOUBLE :: eu usei, pois com o single a tela fica piscando freneticamente.
  • glutIdleFunc :: essa função permite a atualização constante da tela.
  • glutReshapeFunc :: função que passa os argumentos para a "AlteraTamanhoTela".
  • glutMouseFunc :: passa os argumentos como qual o botão, o estado (pressionado ou levantado), e a posição "x" e "y".
  • glutPassiveMotionFunc :: passa os argumentos da posição do mouse (sem clicar).
  • glutKeyboardFunc :: argumentos do teclado (teclas do padrão ASCII).
  • glutSpecialFunc :: argumentos das teclas especiais (setas direcionais, home, delete, etc.).

Pronto!

Agora já dá para criar alguns programas mais interessantes.

   1. Explicação
   2. Primeiro programa e exemplos
   3. Manipulação de eventos do teclado e mouse
   4. Adicionando imagem ao OpenGL
   5. Fontes, links úteis e agradecimentos

Tutorial OpenGL v3.0

Tutorial OpenGL v2.0

Visual Studio no Linux

Ubuntu/Debian/Kali Linux e outros no Android

Tutorial SFML

Escrevendo o caos em C

Utilizando a biblioteca NCURSES - Parte III

Túnel do Tempo: a função itoa()

Programando com uma granada de mão: uma visão da linguagem C

Ponteiros void na linguagem C (parte 2)

#1 Comentário enviado por SamL em 01/08/2014 - 09:11h
Ae cara ficou bom o tutorial.
#2 Comentário enviado por Thihup em 01/08/2014 - 09:15h

[1] Comentário enviado por Sam L. em 01/08/2014 - 09:11h:

Ae cara ficou bom o tutorial.

Valeu mano,sempre me apoiando.
Posso dizer que aquele desafio está encerrado ?

T+
#3 Comentário enviado por SamL em 01/08/2014 - 12:15h
rsrsrs Desafio Completo! You win!
#4 Comentário enviado por albfneto em 01/08/2014 - 12:19h
Muito bom, e diferente, original!
Favoritado e 10.
#5 Comentário enviado por Thihup em 01/08/2014 - 17:58h

[4] Comentário enviado por albfneto em 01/08/2014 - 12:19h:

Muito bom, e diferente, original!
Favoritado e 10.


Valeu Fera
T+
#6 Comentário enviado por razgriz em 02/08/2014 - 22:16h
Favoritado =]
#7 Comentário enviado por Thihup em 03/08/2014 - 23:16h

[6] Comentário enviado por razgriz em 02/08/2014 - 22:16h:

Favoritado =]


Muito Obrigado Mano

É difícil escrever um artigo que todos possam entender

Valor por Favoritar

Não se esqueça de deixar o seu 10,0 (rsrs)

T+

#8 Comentário enviado por thiagomiranda3 em 26/09/2014 - 18:45h
Cara muito bom teu artigo.
Da pra ver que você teve um trampo desgramado pra fazer esse artigo pra nós aqui não é? hehe

Parabéns!

Abraços!
#9 Comentário enviado por Thihup em 26/09/2014 - 18:52h
Hehehehehe , pois é 'chapa' (me chamo Thiago tamb)

Entende algo de C ou C++ ?

Se quiser falar comigo

Skype : thihup

E-mail : thupner@gmail.com

[]'s
#10 Comentário enviado por thiagomiranda3 em 26/09/2014 - 19:00h
Já programei umas estruturas de dados em C kkk, mas como não ponho em prática a algum tempo, já esqueci pacas.
To mais afiado com Java e Ruby agora, por conta da faculdade e do TCC.

É difícil eu ficar online no Skype, mas vou te add aqui pra gente tem uma proza outra hora. hehe

Flw!
Abraços
#11 Comentário enviado por thiago211 em 24/10/2014 - 19:57h
Sempre me surpreendendo thihup.

Parabens chará.
#12 Comentário enviado por flcoutos em 27/05/2015 - 13:22h
Bom o seu Artigo!

#Favoritado

[]s!

-----------------------------------------------------------------------------------
Estou tentando aprender, mas, reconheço que eu não sei nada!
Viva o GNU-Linux "Spira Mirabilis DEBIAN"

Contribuir com comentário

Entre na sua conta para comentar.