Home OpenGL Transformações
No artigo passado entendemos os diferentes sistemas de coordenadas, e vimos como alternar entre esses sistemas. Nesse artigo, entenderemos o que são as transformações, que tipos existem e qual é a sua analogia com a criação de uma imagem real. Esse artigo, entretanto, não cobre a parte matemática das transformações. Se você tem interesse em conhecer como elas são calculadas, você pode conferir o artigo "Matrizes e Transformações", na nossa sessão de Matemática e Física.
O que são transformações?
Como vimos no passado, tudo é definido através de vértices, posicionados no plano cartesiano através de coordenadas em x, y e z. Seria extremamente complicado redefinir todos os pontos de um objeto toda vez que quisessemos posicionar em nosso mundo, ou ainda pior, alterar os pontos de todos os objetos todas as vezes que quiséssemos mover a câmera.
O que então é o ideal? O ideal seria que desenhássemos na nossa ferramenta favorita o objeto uma única vez, salvássemos no centro exato de um sistema de coordenadas qualquer e, só futuramente o posicionássemos no lugar que quiséssemos dentro da cena.
Isso é possível graças as transformações. Elas nada mais são do que cálculos aplicados em todos os nossos vértices para obter um novo posicionamento, de acordo com o nosso desejo. A OpenGL realiza transformações através de cálculos em matrizes, que serão vistas em detalhes no próximo artigo.
Cada transformação tem um objetivo específico, e ocorre em uma etapa do pipeline da OpenGL, descrito na figura abaixo:
Coordenadas do olho
Um dos conceitos mais importantes em transformações e visualizações na OpenGL é o conceito de câmera, ou coordenadas do olho. Imagine-se com uma câmera na mão e posicione-se em qualquer lugar de sua casa. A sua frente, você estará vendo uma série de objetos, posicionados numa posição relativa a de sua câmera. Se, em seguida você se mover, a cena toda se moverá, ajustando a sua nova posição relativa dentro de sua casa.
Portanto, o sistema de coordenadas do olho (ou da câmera), na OpenGL, é aquele em que todos os objetos da cena serão desenhados. Por padrão, esse sistema aponta para o lado negativo de do eixo z (ou seja, para "dentro" do monitor), como na figura abaixo:
Transformações de visualização (Viewing transformations)
A primeira coisa que você faz, quando vai fotografar ou filmar uma cena é posicionar o tripé de sua câmera num bom ângulo e aponta-la em uma direção qualquer. Analogamente, no computador, a primeira tarefa que deve ser realizada é posicionar as coordenadas do olho. Para isso, utilizamos transformações de visualização. Essas transformações afetam todo e qualquer comando dado em sua sequência.
Transformações de modelo
A câmera já está no lugar. Hora de compor a cena a ser fotografada. Você então posiciona os objetos no lugar, gira, arrasta e, se tiver um sortudo em frente a sua câmera, pede para ele falar "xis" e torce para o sorriso sair natual. No computador, o ato de posicionar os objetos é feito através das transformações de modelo.
Mais do que isso, as transformações de modelo atuam sobre o sistema de coordenadas do objeto que está sendo desenhado. Elas dizem como esse sistema deve ser adaptado para se encaixar no sistema do nosso universo. Embora esse conceito pareça um tanto abstrato, vai ficar mais natural a medida que você utiliza-lo.
Existem basicamente 3 tipos de transformações de modelo:
Translação: Afasta o objeto ao longo de um vetor, dentro do seu sistema de coordenadas atual;
Rotação: Gira o sistema de coordenadas do objeto em torno de um ou mais eixos;
Escala: Aumenta ou reduz o tamanho de um objeto. Você pode aplicar escalas diferentes em eixos diferentes, deformando o objeto;
Como a transformação e rotação ocorrem sobre o sistema de coordenadas atual do objeto, sua ordem é importante. Observe na figura abaixo, o que acontece se aplicarmos a rotação antes da translação e vice-versa:
Modelo e visualização. Tem diferença?
Embora a diferença conceitual entre modelo e visualização esteja clara, você pode estar se perguntando. Ok, mas no computador, faz diferença qual usar? Afinal, afastar a câmera para trás não é exatamente o mesmo do que afastar todos os objetos da cena para frente?
Do ponto de vista da implementação, a OpenGL efetivamente realiza todos os cálculos de modelos e de visualização usando apenas uma matriz, chamada de ModelView matrix. A distinção entretanto ainda é bastante válida, mesmo que seja só para facilitar os conceitos para nós, os programadores.
Transformações de projeção
Agora que posicionamos a câmera, os objetos, e nossa vítima está sorrindo, chegou o momento de decidirmos que lente utilizar. Terá uma abertura maior, para pegar a paisagem, ou queremos mesmo focar é nos dentes brancos da pessoa sendo fotografada? Dizemos isso à OpenGL através das transformações de projeção.
O cálculo das transformações representa o momento em que a foto é colocada no filme. Toda a imagem passa pelas lentes e o mundo tridimensional é registrado numa película, em duas dimensões.
Já entendemos, no artigo passado, os tipos de projeção existentes: a ortográfica e a de perspectiva e que impacto elas têm em nossa imagem final. E vimos que, ao ajustar uma projeção de perspectiva, podemos definir o tamanho do campo de visão (análogo a abertura de uma lente).
Transformações de Viewport
Finalmente, é hora de revelarmos a fotografia. Fazemos com que a imagem registrada no filme fique exatamente do tamanho do papel fotográfico, que pode ser 15×21, 3×4, ou outro qualquer. Da mesma forma, também fazemos com que nossa imagem ajuste-se ao tamanho da área de desenho no monitor de nosso jogador seja grande o suficiente para captar cada efeito gráfico que passamos horas programando.
Beginning OpenGL;
22/08/2013 12:17:44 |177.19.133.xxx| fred - Recuperando Nova posicao
...tenho um polígono plano, 2d na tela... Após executar translação ( glTranslatef(x,0,0) ) no eixo x (somente neste último), como recuperar o valor da atual posição do quadrado?
22/08/2013 12:33:56 | Vinícius Godoy de Mendonça
A posição do quadrado será (x,0,0). A OpenGL não guarda informação sobre os polígonos que você desenhou. Quem é responsável por manter essa informação é você.
22/08/2013 13:13:34 |177.19.133.xxx| fredy - re:
Boa Godoy!
i - ...desenho dois personagens equidistantes dentro de retângulos distintos;
ii - ...entre eles há um intervalo de espaço deltaS;
iii - ...Minhas Dúvidas:
i.iii - a área (independente de ser ponto, segmento de reta ou polígono) de colisão distinta de cada personagem é criada com rect (sdl) ou glBegin()/glend() (opengl)?
ii.iii - com o directx eu utilizava rects para definir e detectar colisões, mas qual o melhor caminho a se tomar em opengl quando se tratamos de área de colisão?
22/08/2013 13:27:51 | Vinícius Godoy de Mendonça
A OpenGL é única e exclusivamente um motor gráfico, diferente do DirectX, que inclui funções matemáticas, funções de áudio, etc.
Como detectar colisão na OpenGL é um problema exclusivamente do programador. Eu não usaria SDL_Rects para isso, e sim, uma biblioteca adequada de física como a Box2D (se o game for 2D) ou a BulletPhysics.
Se quiser testar colisões simples, eu recomendo implementar sua classe de Bounding Box ou Bouding Circle/Sphere. AS funções de colisão de retangulos e circulos são trivialmente simples, desde que não sejam aplicadas rotações.
03/09/2013 20:57:11 |177.19.133.xxx| fredy - Box2D
...muito bom o box2d, simples, fácil e prático...
i - Quais as dimensões em pixel é recomendável para uma fase?
ii - ..e em função do item "i" como você setaria o ortho e o view do opengl e quais as escalas recomendáveis?
05/09/2013 11:37:02 |200.207.145.xxx| Anônimo
Sobre dimensões, veja no faq da box:
https://code.google.com/p/box2d/wiki/FAQ
05/09/2013 19:55:07 |177.19.133.xxx| fredy
...sim... eu já havia lido isso no manual... eu que eu queria saber era se há padrões para os tamanhos (em pixel) de uma fase e caso sim, qual a configuração do view mais adequada.... De qualquer forma o conteúdo do pontoV ajudou-me bastande. Obrigado companheiros e parabéns pelos artigos!