Pular para o conteúdo

Tutorial OpenGL

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

Parte 4: Adicionando imagem ao OpenGL

Agora, vamos colocar outras coisas, além de polígonos.

Primeiro, baixem essa (ou qualquer outra imagem .bmp):

Primeira regra das imagem:
  • Precisa ser BMP (pelo menos desse método).
  • A imagem precisa ser de potência de 2 (2^algum número).

Exemplo:

  2^0 = 1x1
  2^1 = 2x2
  2^2 = 4x4
  2^3 = 8x8
  2^4 = 16x16
  2^5 = 32x32
  2^6 = 64x64
  2^7 = 128x128
  2^8 = 264x264

E por aí afora.
Obs.: 1x1 é a resolução.

Eu utilizei o mesmo código como base, apenas coloquei algumas funções a mais.

Segue 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;
int w,h;

GLuint texid1;

char *load_bmp(char * name){

    FILE *f = fopen(name,"rb");
    if(f == NULL) exit(0);
    int of;
    fseek(f, 10, SEEK_SET);
    fread(&of, sizeof(int), 1, f);
    fseek(f, 4, SEEK_CUR);
    fread(&w, sizeof(int), 1, f);
    fread(&h, sizeof(int), 1, f);

    fseek(f, of, SEEK_SET);

    int by = ((w * 3 + 3)/4) * 4 - (w * 3 % 4);
    char *tmp_m = malloc(sizeof(char) * by * h);
    char *m = malloc(sizeof(char) * w * h * 3);
    fread(tmp_m, sizeof(char) * by * h, 1, f);
    int x,y,i;
    for(y = 0; y < h; y++){
        for(x = 0; x < w; x++){
            for(i = 0; i < 3; i++){
                m[3*(w*y + x) + i] = tmp_m[3*(w*y + x) + (2 - i)];
            }
        }
    }
    free(tmp_m);
    return m;
}

GLuint loadTex(char *c){
        char *wa = load_bmp(c);
        GLuint texid;
        glGenTextures(1, &texid);
        glBindTexture(GL_TEXTURE_2D, texid);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, wa);
        free(wa);
        return texid;
}

void colocaImagem(){
        glEnable(GL_TEXTURE_2D);
        glBindTexture(GL_TEXTURE_2D, texid1);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        }

void DesenhaNaTela(void)
{

    colocaImagem();

    // 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);

        glBegin(GL_QUADS);

        glTexCoord3f(-1,1,0);glVertex3f(-1, 1, 0);
        glTexCoord3f(1,1,0);glVertex3f( 1, 1, 0);
        glTexCoord3f(1,-1,0); glVertex3f( 1,-1, 0);
        glTexCoord3f(-1,-1,0);  glVertex3f(-1,-1, 0);

        glEnd();

    angulo+=velocidade;

    glutSwapBuffers();
}

void Inicializa (void)
{
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        texid1 = loadTex("Textura.bmp");
}

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 proporsao =  w * 1.0 / h;

    glMatrixMode(GL_PROJECTION);

    glLoadIdentity();

    glViewport(0, 0, w, h);

    gluPerspective(45.0f, proporsao, 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("Tutorial Imagens");
        Inicializa();
    glutDisplayFunc(DesenhaNaTela);
    glutIdleFunc(DesenhaNaTela);
    glutReshapeFunc(AlteraTamanhoTela);
    glutMouseFunc(CliqueMouse);
    glutPassiveMotionFunc(MovimentoMouse);
    glutKeyboardFunc( Teclado );
    glutSpecialFunc( TeclaEspeciais);
    glutMainLoop();
}

- Nossa, quanto código!
Isso ainda não é muita coisa.

Deixe-me explicar:
  • GLuint texid1; - você está declarando uma unidade do OpenGL chamada "texid1;".
  • A função load_bmp - ela apenas carrega a imagem e aloca um espaço de memória para ela.
  • A função loadTex - coloca a imagem no OpenGL.

colocaImagem :: eu poderia ter colocado todos esses comandos diretamente no "DesenhaNaTela", mas fora fica mais "fácil" de manipular. Essa função permite "jogar" na tela a imagem, mas para isso é necessário definir as vértices.

Por isso, usamos o glTexCoord3f na função "DesenhaNaTela". Como estamos usando apenas um quadrado, as vértices serão iguais aos pontos para formar um quadrado. Se fosse um triângulo, por exemplo, ficaria deformado fazendo desse método.

Inicializa:
  • texid1 = loadTex("Textura.bmp"); - está dizendo que a unidade do OpenGL (texid1) é igual ao retorno da função "loadTex", que recebe como argumento o nome da imagem, e depois é chamada a "load_bmp" para deixá-la compatível com o OpenGL.

Obs.: o nome pode ser alterado, mas mantenha sempre o .bmp.

Ufaa, terminou.

   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 SFML

Ubuntu/Debian/Kali Linux e outros no Android

Visual Studio no Linux

Tutorial OpenGL v2.0

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

LivreNFE - O emissor Nfe open source para Linux

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

Criando um sistema operacional com ASM e C++

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

#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.