Tutorial OpenGL

Tutorial básico de OpenGL com exemplos práticos.

[ Hits: 68.212 ]

Por: Thiago Henrique Hüpner em 01/08/2014


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.

Página anterior     Próxima página

Páginas do artigo
   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
Outros artigos deste autor

Visual Studio no Linux

Tutorial SFML

Tutorial OpenGL v2.0

Ubuntu/Debian/Kali Linux e outros no Android

Tutorial OpenGL v3.0

Leitura recomendada

Aleatoriedade em C

Criando aplicativos para o Mac OS X no GNU/Linux

Reprodução de arquivos WAV com SDL_mixer e linguagem C

Criando programas com suporte a arquivos de configuração com a libConfuse

Introdução à plataforma GNU de desenvolvimento

  
Comentários
[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




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts