Tutorial OpenGL

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

[ Hits: 68.932 ]

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


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.

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

Tutorial OpenGL v2.0

Ubuntu/Debian/Kali Linux e outros no Android

Visual Studio no Linux

Tutorial OpenGL v3.0

Tutorial SFML

Leitura recomendada

Criando um sistema operacional com ASM e C++

Utilizando a biblioteca NCURSES - Parte II

Criação e uso de um interpretador de script BrainFuck em C++

Como aprender a programar e produzir aplicativos usando Euphoria

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

  
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