Como fazer um cubo em OpenGL (com imagens)

Índice:

Como fazer um cubo em OpenGL (com imagens)
Como fazer um cubo em OpenGL (com imagens)

Vídeo: Como fazer um cubo em OpenGL (com imagens)

Vídeo: Como fazer um cubo em OpenGL (com imagens)
Vídeo: Install Windows XP in VirtualBox in 2023 2024, Abril
Anonim

OpenGL é uma ferramenta de programação 3D poderosa usada para desenhar cenas tridimensionais complexas de primitivos simples. Este artigo irá ensiná-lo a desenhar um cubo simples que você pode girar para visualizar em três dimensões!

Para este projeto, você precisará de um editor de código e algum conhecimento de programação C.

Passos

Parte 1 de 3: Configuração inicial

1994315 1 1
1994315 1 1

Etapa 1. Instale o OpenGL Para começar, siga estas etapas para instalar o OpenGL em seu sistema

Se você já tem OpenGL, bem como um compilador C compatível instalado, pode pular esta etapa e ir para a próxima.

1994315 2 1
1994315 2 1

Etapa 2. Crie o documento

Crie um novo arquivo em seu editor de código favorito e salve-o como mycube.c

1994315 3 1
1994315 3 1

Etapa 3. Adicionar #includes

Estas são as inclusões básicas de que você precisará para o seu programa. É importante perceber que, na verdade, existem diferentes inclusões necessárias para os diferentes sistemas operacionais. Certifique-se de incluir tudo isso para garantir que seu programa seja versátil e possa ser executado por qualquer usuário.

    // Inclui #include #include #include #define GL_GLEXT_PROTOTYPES #ifdef _APPLE_ #include #else #include #endif

1994315 4 1
1994315 4 1

Etapa 4. Adicionar protótipos de função e variáveis globais

Sua próxima etapa é declarar alguns protótipos de função.

    // Protótipos de função void display (); void specialKeys (); // Variáveis globais double rotate_y = 0; double rotate_x = 0;

1994315 5 1
1994315 5 1

Etapa 5. Configure a função principal ()

    int main (int argc, char * argv ) {// Inicializar GLUT e processar os parâmetros do usuário glutInit (& argc, argv); // Solicitar janela true color com buffer duplo com Z-buffer glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);

  • Esta declaração configura seu ambiente. Uma grande coisa a lembrar ao escrever programas OpenGL é que você deve pedir tudo. Isso requer que você tenha um maior entendimento de como seu programa funciona e o que você precisa incluir para obter a funcionalidade desejada. Nesta linha, você configurará a exibição com buffer duplo, cor RGB e um Z-buffer.
  • Buffer duplo é uma técnica usada em programas gráficos para eliminar um problema que surge devido ao modo como as imagens são desenhadas na tela. Cada vez que você redesenha a cena, a exibição deve primeiro ser apagada e, em seguida, as novas informações serão desenhadas. Sem o buffer duplo, você observará um efeito de oscilação conforme a tela é apagada e redesenhada repetidamente.
  • Este problema é corrigido adicionando um segundo buffer para desenhar. Com este método, uma imagem é desenhada para o primeiro buffer e esse buffer é mostrado a você. O próximo quadro será desenhado para o segundo buffer e quando isso for feito, os dois buffers irão trocar de lugar. Você verá imediatamente o segundo buffer, mas, escondido de nós, o primeiro buffer está sendo apagado e redesenhado com o terceiro quadro que será trocado quando concluído.
  • Você também deseja habilitar o Cor RGB sistema em sua janela.
  • Z-buffering é como você obtém os efeitos 3D que deseja. OpenGL usa um sistema de coordenadas tridimensional com eixos x, y e z. Para dar a impressão de que um objeto está mais próximo de você, sua posição no eixo z é aumentada; no entanto, para fazê-lo parecer mais distante, sua posição no eixo z é diminuída.
1994315 6 1
1994315 6 1

Etapa 6. Crie a janela

A próxima etapa é crie a janela dentro do qual você desenhará o cubo. Neste tutorial, a janela é chamada de "Cubo incrível".

    // Criar janela glutCreateWindow ("Awesome Cube");

1994315 7 1
1994315 7 1

Etapa 7. Habilite o teste de profundidade

OpenGL é uma linguagem estrita, pois não assume que nenhum recurso especial esteja ativado. Para que seu programa seja exibido corretamente em 3 dimensões usando o Z-buffer que você examinou anteriormente, você precisa habilitar teste de profundidade. Conforme você continua a explorar o OpenGL, você descobrirá muitos recursos que precisará ativar, incluindo iluminação, texturas, faceamento e muito mais.

    // Habilita o teste de profundidade do Z-buffer glEnable (GL_DEPTH_TEST);

1994315 8 1
1994315 8 1

Etapa 8. Adicionar funções de retorno de chamada

Aqui estão as funções de retorno de chamada para as quais você escreveu os protótipos anteriormente. Cada vez que passar pelo loop principal, essas funções serão chamadas. A função de exibição redesenha a cena com base em quaisquer alterações nas variáveis que foram feitas desde a chamada anterior. A função specialKeys nos permite interagir com o programa.

    // Funções de retorno de chamada glutDisplayFunc (display); glutSpecialFunc (specialKeys);

1994315 9 1
1994315 9 1

Etapa 9. Inicie o MainLoop

Isso irá chamar a função principal até que você feche o programa para permitir animações e interação do usuário.

    // Passe o controle para o GLUT para eventos glutMainLoop (); // Retornar ao sistema operacional return 0; }

Parte 2 de 3: A função display ()

1994315 10 1
1994315 10 1

Etapa 1. Compreenda a finalidade desta função

Todo o trabalho de desenho do seu cubo será feito nesta função. A ideia geral por trás de seu cubo é desenhar todos os seis lados individualmente e colocá-los na posição apropriada.

Conceitualmente, cada lado será desenhado definindo os quatro cantos e permitindo que o OpenGL conecte as linhas e as preencha com uma cor que você definir. Abaixo estão as etapas para fazer isso

1994315 11 1
1994315 11 1

Etapa 2. Adicione glClear ()

A primeira etapa que você precisa realizar nesta função é limpe a cor e o buffer Z. Sem essas etapas, os desenhos antigos ainda podem ser visíveis sob os novos desenhos e os objetos desenhados não estariam no local correto na tela.

    void display () {// Limpar tela e Z-buffer glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

1994315 12 1
1994315 12 1

Etapa 3. Adicione glBegin () e glEnd ()

OpenGL define objetos como combinações de diferentes polígonos. Usando o glBegin () comando, você efetivamente coloca um lápis que desenhará uma forma. Para levantar o lápis e começar uma nova forma, você deve usar o glEnd () comando. Neste tutorial, você usará GL_POLYGON para desenhar cada lado do cubo, mas é possível usar outras opções de parâmetro, como GL_LINE, GL_QUAD ou GL_TRIANGLE para criar outras formas.

  • Aqui você começará com a frente do seu cubo. Mais tarde, você adicionará cor a todos os 6 lados.
  • // Lado multicolorido - FRONT glBegin (GL_POLYGON); // Os vértices serão adicionados na próxima etapa glEnd ();

1994315 13 1
1994315 13 1

Etapa 4. Adicione glVertex3f ()

Depois de declarar que deseja iniciar seu polígono, você precisa definir os vértices do objeto. glVertex tem vários formulários, dependendo do que você deseja fazer com seu objeto.

  • A primeira é em quantas dimensões você está trabalhando. O 3 acima em glVertex3f diz que você está desenhando em 3 dimensões. Também é possível trabalhar em 2 ou 4 dimensões. O f acima em glVertex3f indica que você está trabalhando com números de ponto flutuante. Você também pode usar shorts, inteiros ou duplos.
  • Observe que esses pontos são definidos em um sentido anti-horário maneiras. Isso não é muito importante no momento, mas quando você começar a trabalhar com iluminação, texturas e faceamento, isso se tornará extremamente importante, então adquira o hábito de definir seus pontos no sentido anti-horário agora.
  • Adicione adicione os vértices entre as linhas glBegin () e glEnd ().
  • // Lado multicolorido - FRONT glBegin (GL_POLYGON); glVertex3f (-0,5, -0,5, -0,5); // P1 glVertex3f (-0,5, 0,5, -0,5); // P2 glVertex3f (0,5, 0,5, -0,5); // P3 glVertex3f (0,5, -0,5, -0,5); // P4 glEnd ();

1994315 14 1
1994315 14 1

Etapa 5. Adicione glColor3f ()

glColor funciona de maneira semelhante ao glVertex. Você pode definir pontos como shorts, inteiros, duplos ou floats. Cada cor tem um valor de 0 a 1. Todos os 0s tornam o ponto preto e todos os 1s tornam o ponto branco. O 3 em glColor3f () se refere ao sistema de cores RGB sem canal alfa. O alfa de uma cor define sua transparência. Para alterar o nível alfa, use glColor4f () com o último parâmetro sendo um valor de 0 a 1 de opaco para transparente.

  • Quando você chama glColor3f (), cada vértice desenhado daquele ponto em diante terá aquela cor. Portanto, se você deseja que todos os quatro vértices sejam vermelhos, apenas defina a cor uma vez a qualquer momento antes dos comandos glVertex3f () e todos os vértices serão vermelhos.
  • O lado frontal definido abaixo mostra como definir uma nova cor para cada vértice. Ao fazer isso, você pode ver uma propriedade interessante das cores OpenGL. Como cada vértice do polígono tem sua própria cor, o OpenGL irá mesclar automaticamente as cores! A próxima etapa mostrará como atribuir quatro vértices com a mesma cor.
  • // Lado multicolorido - FRONT glBegin (GL_POLYGON); glColor3f (1,0, 0,0, 0,0); glVertex3f (0,5, -0,5, -0,5); // P1 é vermelho glColor3f (0.0, 1.0, 0.0); glVertex3f (0,5, 0,5, -0,5); // P2 é verde glColor3f (0.0, 0.0, 1.0); glVertex3f (-0,5, 0,5, -0,5); // P3 é azul glColor3f (1.0, 0.0, 1.0); glVertex3f (-0,5, -0,5, -0,5); // P4 é roxo glEnd ();

1994315 15 1
1994315 15 1

Etapa 6. Manuseie os outros lados

Descubra qual será a localização de cada vértice para os outros cinco lados do cubo, mas para simplificar, eles foram calculados para você e estão incluídos no função display final () abaixo.

    // Lado branco - VOLTAR glBegin (GL_POLYGON); glColor3f (1,0, 1,0, 1,0); glVertex3f (0,5, -0,5, 0,5); glVertex3f (0,5, 0,5, 0,5); glVertex3f (-0,5, 0,5, 0,5); glVertex3f (-0,5, -0,5, 0,5); glEnd (); // Lado roxo - RIGHT glBegin (GL_POLYGON); glColor3f (1,0, 0,0, 1,0); glVertex3f (0,5, -0,5, -0,5); glVertex3f (0,5, 0,5, -0,5); glVertex3f (0,5, 0,5, 0,5); glVertex3f (0,5, -0,5, 0,5); glEnd (); // Lado verde - LEFT glBegin (GL_POLYGON); glColor3f (0,0, 1,0, 0,0); glVertex3f (-0,5, -0,5, 0,5); glVertex3f (-0,5, 0,5, 0,5); glVertex3f (-0,5, 0,5, -0,5); glVertex3f (-0,5, -0,5, -0,5); glEnd (); // Lado azul - TOPO glBegin (GL_POLYGON); glColor3f (0,0, 0,0, 1,0); glVertex3f (0,5, 0,5, 0,5); glVertex3f (0,5, 0,5, -0,5); glVertex3f (-0,5, 0,5, -0,5); glVertex3f (-0,5, 0,5, 0,5); glEnd (); // Lado vermelho - BOTTOM glBegin (GL_POLYGON); glColor3f (1,0, 0,0, 0,0); glVertex3f (0,5, -0,5, -0,5); glVertex3f (0,5, -0,5, 0,5); glVertex3f (-0,5, -0,5, 0,5); glVertex3f (-0,5, -0,5, -0,5); glEnd (); glFlush (); glutSwapBuffers (); }

  • Também queremos adicionar duas últimas linhas de código para esta função. Estes são glFlush ();

    e glutSwapBuffers ();

    o que nos dá o efeito de buffer duplo sobre o qual você aprendeu antes.

Parte 3 de 3: Interatividade do usuário

1994315 16 1
1994315 16 1

Etapa 1. Adicione specialKeys ()

Você está quase terminando, mas no momento, você pode desenhar um cubo, mas não tem como girá-lo. Para fazer isso, você vai crie um specialKeys () função que nos permite pressionar as teclas de seta e girar o cubo!

  • Esta função é a razão pela qual você declarou as variáveis globais rotate_x e rotate_y. Quando você pressiona as teclas de seta para a direita e para a esquerda, rotate_y será incrementado ou decrementado em 5 graus. Da mesma forma, quando você pressiona as teclas de seta para cima e para baixo, rotate_x muda de acordo.
  • void specialKeys (int key, int x, int y) {// Seta para a direita - aumenta a rotação em 5 graus if (key == GLUT_KEY_RIGHT) rotate_y + = 5; // Seta para a esquerda - diminui a rotação em 5 graus else if (key == GLUT_KEY_LEFT) rotate_y - = 5; else if (key == GLUT_KEY_UP) rotate_x + = 5; else if (chave == GLUT_KEY_DOWN) rotate_x - = 5; // Solicitar atualização de exibição glutPostRedisplay (); }

1994315 17 1
1994315 17 1

Etapa 2. Adicione glRotate ()

Sua última afirmação é adicionar a instrução que girará seu objeto. Volte para a função display () e antes do lado FRONT, adicione estas linhas:

    // Reinicia as transformações glLoadIdentity (); // Girar quando o usuário muda rotate_x e rotate_y glRotatef (rotate_x, 1.0, 0.0, 0.0); glRotatef (rotate_y, 0,0, 1,0, 0,0); // Lado multicolorido - FRONT….

  • Primeiro observe que a sintaxe de glRotatef () é semelhante ao de glColor3f () e glVertex3f (), mas sempre requer 4 parâmetros. O primeiro parâmetro é o grau de rotação a ser aplicado. Os próximos três parâmetros definem em qual eixo girar, sendo o primeiro o eixo x, o segundo sendo o eixo y e o terceiro sendo o eixo z. No momento, você só precisa girar em torno dos eixos xey.
  • Todas as transformações que você escreve em seu programa precisam de linhas semelhantes a esta. Conceitualmente, você pode pensar nisso como girar seu objeto em torno do eixo x pelo valor definido por rotate_x e, em seguida, girar em torno do eixo y por rotate_y. No entanto, o OpenGL combina todas essas instruções em uma transformação de matriz. Cada vez que você chama a função de exibição, você constrói uma matriz de transformação e glLoadIdentity () garante que você começará com uma nova matriz em cada passagem.
  • As outras funções de transformação que você pode aplicar são glTranslatef () e glScalef (). Essas funções são semelhantes a glRotatef () com a exceção de que elas usam apenas 3 parâmetros, os valores x, y e z para traduzir ou dimensionar o objeto.
  • Para obter o efeito correto ao aplicar todas as três transformações a um objeto, você precisa aplicá-las na ordem correta. Sempre escreva-os na ordem glTranslate, glRotate, então glScale. O OpenGL aplica essencialmente as transformações de maneira ascendente. Para entender isso, tente imaginar como seria um cubo 1x1x1 simples com as transformações se o OpenGL as aplicasse de cima para baixo e se o OpenGL as aplicasse de baixo para cima.
1994315 18 1
1994315 18 1

Etapa 3. Adicione os seguintes comandos para dimensionar o cubo em 2 ao longo do eixo x, 2 ao longo do eixo y, girar o cubo 180 graus em torno do eixo y e transladar o cubo em 0,1 ao longo do eixo x

Certifique-se de organizá-los, assim como os comandos glRotate () anteriores, na ordem correta, conforme descrito acima. (Se você não tiver certeza, isso é feito no código final no final do tutorial.)

    // Outras transformações glTranslatef (0.1, 0.0, 0.0); glRotatef (180, 0,0, 1,0, 0,0); glScalef (2,0, 2,0, 0,0);

1994315 19 1
1994315 19 1

Etapa 4. Compile e execute seu código

Supondo que você esteja usando gcc como seu compilador, execute esses comandos em seu terminal para compilar e testar seu programa.

    No Linux: gcc cube.c -o cube -lglut -lGL./ mycube No Mac: gcc -o foo foo.c -framework GLUT -framework OpenGL./ mycube No Windows: gcc -Wall -ofoo foo.c -lglut32cu - lglu32 -lopengl32./ mycube

1994315 20 1
1994315 20 1

Etapa 5. Verifique seu código completo

Deve ser assim:

    // // Arquivo: mycube.c // Autor: Matt Daisley // Criado: 2012-04-25 // Projeto: Código-fonte para Fazer um Cubo em OpenGL // Descrição: Cria uma janela OpenGL e desenha um cubo 3D / / Que o usuário pode girar usando as teclas de seta // // Controles: Seta para a esquerda - Girar para a esquerda // Seta para a direita - Girar para a direita // Seta para cima - Girar para cima // Seta para baixo - Girar para baixo // ------ -------------------------------------------------- - // Inclui // ------------------------------------------- --------------- #include #include #include #define GL_GLEXT_PROTOTYPES #ifdef _APPLE_ #include #else #include #endif // ------------- --------------------------------------------- // Function Prototypes / / ------------------------------------------------- --------- void display (); void specialKeys (); // ------------------------------------------------ ---------- // Variáveis globais // ---------------------------------- ------------------------ double rotate_y = 0; double rotate_x = 0; // ------------------------------------------------ ---------- // display () Função de retorno de chamada // ------------------------------- --------------------------- void display () {// Limpar tela e Z-buffer glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Reinicia as transformações glLoadIdentity (); // Outras transformações // glTranslatef (0.1, 0.0, 0.0); // Não incluído // glRotatef (180, 0.0, 1.0, 0.0); // Não incluído // Girar quando o usuário muda rotate_x e rotate_y glRotatef (rotate_x, 1.0, 0.0, 0.0); glRotatef (rotate_y, 0,0, 1,0, 0,0); // Outras transformações // glScalef (2.0, 2.0, 0.0); // Não incluído // Lado multicolorido - FRONT glBegin (GL_POLYGON); glColor3f (1,0, 0,0, 0,0); glVertex3f (0,5, -0,5, -0,5); // P1 é vermelho glColor3f (0.0, 1.0, 0.0); glVertex3f (0,5, 0,5, -0,5); // P2 é verde glColor3f (0.0, 0.0, 1.0); glVertex3f (-0,5, 0,5, -0,5); // P3 é azul glColor3f (1.0, 0.0, 1.0); glVertex3f (-0,5, -0,5, -0,5); // P4 é roxo glEnd (); // Lado branco - BACK glBegin (GL_POLYGON); glColor3f (1,0, 1,0, 1,0); glVertex3f (0,5, -0,5, 0,5); glVertex3f (0,5, 0,5, 0,5); glVertex3f (-0,5, 0,5, 0,5); glVertex3f (-0,5, -0,5, 0,5); glEnd (); // Lado roxo - RIGHT glBegin (GL_POLYGON); glColor3f (1,0, 0,0, 1,0); glVertex3f (0,5, -0,5, -0,5); glVertex3f (0,5, 0,5, -0,5); glVertex3f (0,5, 0,5, 0,5); glVertex3f (0,5, -0,5, 0,5); glEnd (); // Lado verde - LEFT glBegin (GL_POLYGON); glColor3f (0,0, 1,0, 0,0); glVertex3f (-0,5, -0,5, 0,5); glVertex3f (-0,5, 0,5, 0,5); glVertex3f (-0,5, 0,5, -0,5); glVertex3f (-0,5, -0,5, -0,5); glEnd (); // Lado azul - TOPO glBegin (GL_POLYGON); glColor3f (0,0, 0,0, 1,0); glVertex3f (0,5, 0,5, 0,5); glVertex3f (0,5, 0,5, -0,5); glVertex3f (-0,5, 0,5, -0,5); glVertex3f (-0,5, 0,5, 0,5); glEnd (); // Lado vermelho - BOTTOM glBegin (GL_POLYGON); glColor3f (1,0, 0,0, 0,0); glVertex3f (0,5, -0,5, -0,5); glVertex3f (0,5, -0,5, 0,5); glVertex3f (-0,5, -0,5, 0,5); glVertex3f (-0,5, -0,5, -0,5); glEnd (); glFlush (); glutSwapBuffers (); } // ----------------------------------------------- ----------- // specialKeys () Função de retorno de chamada // ------------------------------ ---------------------------- void specialKeys (int key, int x, int y) {// Seta para a direita - aumenta a rotação em 5 grau if (chave == GLUT_KEY_RIGHT) rotate_y + = 5; // Seta para a esquerda - diminui a rotação em 5 graus else if (key == GLUT_KEY_LEFT) rotate_y - = 5; else if (chave == GLUT_KEY_UP) rotate_x + = 5; else if (key == GLUT_KEY_DOWN) rotate_x - = 5; // Solicitar atualização de exibição glutPostRedisplay (); } // ----------------------------------------------- ----------- // função principal // ------------------------------- --------------------------- int main (int argc, char * argv ) {// Inicializar o GLUT e processar os parâmetros do usuário glutInit (& argc, argv); // Solicitar janela true color com buffer duplo com Z-buffer glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); // Criar janela glutCreateWindow ("Awesome Cube"); // Habilita o teste de profundidade do Z-buffer glEnable (GL_DEPTH_TEST); // Funções de retorno de chamada glutDisplayFunc (display); glutSpecialFunc (specialKeys); // Passe o controle para o GLUT para eventos glutMainLoop (); // Retornar ao sistema operacional return 0; }

Recomendado: