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.
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.
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.0Agora 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ânguloAgora 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 UnitsAgora, 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 }
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 } }
"[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.
Organizado
e escrito originalmente por Jeff Molofee (NeHe)
Adapatado
para a Língua Portuguesa por Aldo von Wangenheim (UFSC)