Lição 2.1:  Meu primeiro polígono em OpenGL

Muito do código deste tutorial foi escrito originalmente por Jeff Molofee e Fredric Echols e é  uma tradução do OpenGL Tutorial de Jeff Molofee & Neon Helium. Jeff o reescreveu totalmente em Janeiro de 2000. Durante a tradução ao português, a formatação original, com muitas tabelas e figuras mostrando bordas de tabelas para o texto explicativo, foi modificada de forma a facilitar a carga das páginas e a torná-las mais leves.

  1. Objetivos
  2. Desenhando Triângulos e Quadrados
  3. Modificações no Resto do Programa
  4. Links para Código Fonte

Objetivos

No primeiro tutorial vimos como criar uma janela OpenGL e qual a estrutura geral de um programa OpenGL usando GLUT.
Neste tutorial vamos ver como criamos tanto triângulos como quadrados. Utilizaremos os objetos  GL_TRIANGLES para triângulos e  GL_QUADS para quadriláteros.


Desenhando Triângulos e Quadrados

Utilizando o código do primeiro tutorial, adicionaremos linhas de código à função DrawGLScene(). Na verdade, vamos reescrever toda a função. Se você quer reaproveitar o código da última aula, simplesmente substitua a função de desenho daquele código pela que vamos descrever aqui.

int DrawGLScene(GLvoid)                                                 // Aqui nós desenhamos tudo
{
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);             // Limpe a tela e o Z-Buffer
        glLoadIdentity();                                               // Resete a visualização.
Quando você invoca glLoadIdentity() o que ocorre, é que você se move ao centro do window, com a eixo X da esquerda para a direita, o eixo Y para cima e o eixo Z para fora do vídeo. O centro do vídeo é a posição X,Y 0,0. No eixo Z, números negativos vão para dentro do vídeo, positivos para fora.

glTranslatef(x, y, z)move se ao longo dos eixos  X, Y e Z. A linha de código abaixo move a caneta de desenho 1,5 unidades à esquerda e 6 unidades para longe do usuário, ou seja, para dentro do vídeo.

        glTranslatef(-1.5f,0.0f,-6.0f);                                 // Move Left 1.5 Units And Into The Screen 6.0
Agora que nos movemos para a parte esquerda do vídeo e longe que chega do usuário para que ele possa enxergar tudo o que vamos desenhar, vamos criar um triângulo. glBegin(GL_TRIANGLES) significa que vamos iniciar um bloco de código onde será realizado o desenho de um triângulo e glEnd() comunica OpenGL que terminamos. Da mesma forma, se quisermos desenhar objetos definidos por 4 pontos, usaremos GL_QUADS, embora a grande maioria das placas de vídeo renderizem tudo como triângulos de qualquer forma. Se você quiser criar objetos com mais de 4 pontos, utilize GL_POLYGON.

A estrutura glBegin()...glEnd(), apesar de serem chamadas a funções, define uma espécie de extensão da Linguagem C, criando uma mudança de modo de operação no OpenGL que emula um bloco de programa, onde comandos podem ser executados em um contexto específico, como por exemplo o contexto TRIÂNGULO.

Se quiséssemos desenhar mais de um triângulo, bastaria incluir mai três linhas de código no bloco, desenhando mais três pontos, estando todas as seis linhas entre glBegin(GL_TRIANGLES) e glEnd(). Não existe razão para colocar um glBegin(GL_TRIANGLES) e um glEnd() em torno de cada triângulo que você vai desenhar. Se você vai desenhar quadriláteros, pode trabalhar da mesma forma, lembrando que deve usar múltiplos de quatro no número de pontos. No caso de um polígono, a coisa muda de figura: como o polígono pode ter qualquer número de pontos, todos o comandos no bloco são interpretados como sendo pontos do mesmo polígono, até glEnd().

A primeira linha após glBegin, seta o primeiro ponto de nosso polígono. O primeiro valor de glVertex é a coordenada X, o segundo a coordenada Y e o terceiro a coordenada Z do ponto.  glEnd() indica a  OpenGL que não há mais pontos. O triângulo preenchido será então mostrado na tela. Observe que os pontos que definimos foram criados com posições relativas à translação global da caneta realizada em glTranslatef(-1.5f,0.0f,-6.0f); Em outras palavras, glTranslatef(-1.5f,0.0f,-6.0f) definiu uma nova origem para o sistema de coordenadas com base na qual glVertex3f opera.

        glBegin(GL_TRIANGLES);                                          // início triângulo
                glVertex3f( 0.0f, 1.0f, 0.0f);                          // Topo
                glVertex3f(-1.0f,-1.0f, 0.0f);                          // Esquerda embaixo
                glVertex3f( 1.0f,-1.0f, 0.0f);                          // Direita embaixo
        glEnd();                                                        // fim triângulo
Agora que temos um triângulo desenhado do lado esquerdo da tela, temos de nos mover para o lado direito para desenhar nosso fantástico quadrado. Para isso usamos glTranslatef() novamente. Agora temos de no mover 1,5 unidades para a direita do centro do vídeo. Como estamos à esquerda, movemo-nos 3 unidades para chegar lá.
        glTranslatef(3.0f,0.0f,0.0f);                                   // Move Right 3 Units
Agora, usando GL_QUADS vamos desenhar nosso quadrado.  A única diferença para a criação do triângulo é que necessitamos de uma linha de código a mais especificando o quarto ponto. Desenharemos o objeto no sentido dos ponteiros do relógio. Dessa forma estaremos vendo o quadrado de trás. Em OpenGL objetos desenhados no sentido anti-horário são vistos de frente e objetos desenhados no sentido horário vistos por trás, ou seja, estão de costas para o usuário. Como nosso quadrado usa as característica sdefault do OpenGL, cor branca e visual opaco, isto não faz a mínima diferença no momento, mas é bom sabermos.
        glBegin(GL_QUADS);                                              // Draw A Quad
                glVertex3f(-1.0f, 1.0f, 0.0f);                          // Top Left
                glVertex3f( 1.0f, 1.0f, 0.0f);                          // Top Right
                glVertex3f( 1.0f,-1.0f, 0.0f);                          // Bottom Right
                glVertex3f(-1.0f,-1.0f, 0.0f);                          // Bottom Left
        glEnd();                                                        // Done Drawing The Quad
        return TRUE;                                                    // Keep Going
}


Modificações no Resto do Programa

Finalmente modificamos o título da Janela..........
 

                        if (keys[VK_F1])                                // Is F1 Being Pressed?
                        {
                                keys[VK_F1]=FALSE;                      // If So Make Key FALSE
                                KillGLWindow();                         // Kill Our Current Window
                                fullscreen=!fullscreen;                 // Toggle Fullscreen / Windowed Mode
                                // Recreate Our OpenGL Window ( Modified )
                                if (!CreateGLWindow("NeHe's First Polygon Tutorial",640,480,16,fullscreen))
                                {
                                        return 0;                       // Quit If Window Was Not Created
                                }
                        }




Markus Knauer comenta: In the book ("OpenGL Programming Guide: The Official Guide to Learning OpenGL, Release 1", J. Neider, T. Davis, M. Woo, Addison-Wesley, 1993) the following paragraph will clearly explain what NeHe means when he refers to movement by units in OpenGL:

"[I mentioned] inches and millimeters - do these really have anything to do with OpenGL? The answer is, in a word, no. The projection and other transformations are inheritly unitless. If you want to think of the near and far clipping planes as located at 1.0 and 20.0 meters, inches, kilometers, or leagues, it's up to you. The only rule is that you have to use consistent unit of measurement."

In this tutorial I have tried to explain in as much detail, every step involved in drawing polygons, and quads on the screen using OpenGL. If you have comments or questions please email me. If you feel I have incorrectly commented something or that the code could be done better in some sections, please let me know. I want to make the best OpenGL tutorials I can. I'm interested in hearing your feedback.



Links para Código Fonte

Organizado e escrito originalmente por Jeff Molofee (NeHe)
Adapatado para a Língua Portuguesa por Aldo von Wangenheim (UFSC)