Ponto V!

Home OpenGL Conhecendo a OpenGL
Vinícius Godoy de Mendonça
Conhecendo a OpenGLImprimir
Escrito por Vinícius Godoy de Mendonça

Embora nos artigos anteriores tenhamos desenhado e rotacionado um triângulo, falamos muito pouco sobre o que é a OpenGL e como ele funciona. Neste artigo, vamos conhecer um pouco da história da OpenGL, do seu propósito e da sua arquitetura.

História do padrão OpenGL

Na década de 80, cada fabricante de hardware tinha seu próprio conjunto de instruções para desenho de gráficos 2D e 3D. Construir aplicações com essas tecnologias, que suportassem vários hardwares era um verdadeiro desafio. O esforço era constantemente duplicado e havia pouco espaço para companhias menores e sem capital entrarem nesse mercado.

Em meados dos anos 80 um padrão surgiu na indústria. Chamado PHIGS (sigla de Programmer’s Hierarchical Graphics System), começou a ser adotado por grandes fabricantes da época. Entretanto, embora tenha sido reconhecido por entidades como a ANSI e a ISO, o padrão começou a ser considerado complicado e desatualizado.

No final dos anos 80, a Silicon Graphics Inc. (SGI), criou um padrão chamado IRIS GL, que não só começou a chamar atenção da indústria, como também foi considerado o estado da arte de uma API gráfica. Consideravelmente mais fácil de usar, a API começou a tornar-se um padrão de facto na indústria.

Entretanto, grandes empresas produtoras da hardware, como a Sun e a IBM, ainda eram capazes de fabricar hardware adotando o padrão PHIGS. Isso levou a SGI a tomar uma decisão para que a adoção de sua API fosse impulsionada: torna-la um padrão público, para que todos os fabricantes de placas de vídeo pudessem adotá-lo.

A SGI considerou que a API Iris continha muito código proprietário e portanto não poderia ser aberta. Ela também lidava com questões não tão relacionadas ao desenho 2D e 3D, como gerenciamento de janelas, teclado e mouse. Por outro lado, não era do interesse da Silicon Graphics perder clientes, o que os levou a buscar uma solução ainda compatível.

Como resultado disso, o padrão OpenGL foi criado. Desde 1992, o padrão é mantido pelo ARB (Architecture Review Board), um conselho formado por empresas como a 3DLabs, ATI, Dell, Evans&Sutherland, HP, IBM, Intel, Matrox, NVIDIA, Sun e, logicamente, a Silicon Graphics. O papel desse conselho é manter a especificação e indicar quais recursos serão adicionados a cada versão. A versão mais atual do OpenGL até hoje é a 2.1, embora já se especule sobre o OpenGL 3.0.

Os projetistas do OpenGL sabiam de duas coisas. A primeira é que fabricantes de hardware gostariam de adicionar recursos próprios, sem que tivessem que esperar para esses recursos estarem oficialmente aceitos no padrão. Para resolver esse problema, eles incluíram uma maneira de estender o OpenGL. Muitas vezes, essas extensões são interessantes o suficiente para que outros vendedores de hardware as adotem. Então, quando elas são consideradas suficientemente abrangentes, ou suficientemente importantes, a ARB pode ser promovê-las para que façam parte do padrão oficial. Praticamente todas as modificações recentes do padrão começaram como extensões, a grande maioria devido ao mercado de jogos.

Em segundo lugar, os projetistas também sabiam que muitos hardwares não seriam poderosos o suficiente para abraçar todo o padrão. Por isso, também incluíram extensões de software, que permitiam emular essas funcionalidades. Isso resolvia um problema sério que ocorria com a Iris: O da aplicação simplesmente não rodar pela falta de um ou outro recurso.

Em 1995 a Microsoft lançou o Direct3D, que se tornou um dos principais concorrentes do OpenGL. O Direct3D vem integrado juntamente ao DirectX, que contém soluções também para som, música e rede.

Arquitetura da biblioteca OpenGL

logoO padrão OpenGL é implementado na forma de uma de uma biblioteca com centenas de funções, que fornecem acesso a praticamente todos os recursos do hardware de vídeo. Internamente, ele age como uma máquina de estados, que de maneira bem específica dizem a placa de vídeo o que fazer. Usando as funções da API, você pode ligar ou desligar vários aspectos dessa máquina, tais como a cor atual, se transparência será usada, se cálculos de iluminação devem ser feitos, se haverá ou não o efeito de neblina, e assim por diante. É importante conhecer cada um desses estados, pois não é incomum a obtenção de resultados indesejados simplesmente por deixar um ou outro estado definido de maneira incorreta.

A OpenGL também foi projetada para funcionar mesmo que o computador que esteja exibindo os gráficos não seja o mesmo que contém o programa gráfico, como no caso de dois computadores ligados em rede. O computador que gera os comandos é chamado cliente, enquanto o que recebe e executa os comandos de pintura é chamado de servidor. O formato da transmissão desses comandos (protocolo) também é padronizado, então é possível que duas máquinas com sistemas operacionais e hardwares diferentes se comuniquem dessa forma. Se a OpenGL não está sendo executada numa rede, o computador é considerado ao mesmo tempo cliente e servidor.

Essa decisão de design tem uma consequência muito importante: os comandos da OpenGL não são imediatamente jogados para o hardware. Eles são agrupados para serem enviados mais tarde – o que não só otimiza o uso da rede, mas também abre margem para outras otimizações. Por consequência, um erro comum de muitos programadores é tentar medir o tempo levado pelos comandos de pintura simplesmente adicionando funções antes e depois de um comando (ou conjunto de comandos) o que, nessa arquitetura, certamente gerará resultados inválidos. Afinal, não há garantias de que os comandos serão imediatamente executados, e, o que acaba sendo medindo com essa estratégia é a velocidade que a OpenGL armazena os comandos para futura execução.

Forçar a execução dos comandos também é uma má idéia, já que com isso muitas otimizações simplesmente são desprezadas. Nessa arquitetura, a forma mais confiável de se medir a performance é através de software especial, que pode ser obtido na própria página da OpenGL.

Rendering Pipeline

O núcleo da OpenGL é conhecido como “rendering pipeline”, descrito no desenho abaixo:

renderingPipeline

É importante notar que a OpenGL lida tanto com o desenho na forma vetorial, definido por vértices, como com mapas de bits, definidos pixel-a-pixel. Os principais elementos desse pipeline estão descritos abaixo:

  • Display Lists: Todos os dados, sejam de os vértices de geometrias ou pixels, podem ser salvos numa display list para uso atual ou posterior;
  • Avaliadores (Evaluators): Todas as primitivas geométricas, na OpenGL são descritas por vértices. Curvas e superfícies paramétricas podem ser descritas por fórmulas, que devem ser avaliadas, para recaírem nos vértices. Quem faz a derivação dessas fórmulas são os Evaluators.
  • Operações pré-vértices: As operações pré-vertice convertem os vértices em primitivas de desenho. Nessa etapa, cada vértice é convertido em matrizes 4×4, então cálculos são realizados para que sejam convertidos do espaço 3D para as coordenadas de tela. Essa etapa ainda realiza operações de cálculos de textura, iluminação, materiais, etc. de acordo com quais estados tenham sido habilitados;
  • Montagem de primitivas (primitive assembly): A fase de montagem de primitivas preocupa-se com a eliminação das partes da geometria que estejam fora do plano. Essa fase também aplica os cálculos de perspectiva, o que faz com que objetos distantes pareçam menores em relação a objetos próximos. Se cálculos de culling estiverem ativos, parte dos objetos também podem ser desprezadas. É aqui também que decide-se se um polígono deve ser desenhado através de pontos ou linhas;
  • Operações com Pixels: Enquanto os dados geométricos seguem pelo rendering pipeline, os mapas pixels passam por diferentes tipos de transformação. Primeiramente, os pixels são descompactados de acordo com o seu número de componentes, então eles tem sua escala ajustada, seu formato final é calculado, parte de sua área é recortada e então são enviados para o passo chamado rasterization.
  • Montagem de texturas (texture assembly): Permite a aplicação de imagens como texturas das geometrias, para que elas pareçam mais realistas. Algumas implementações da OpenGL podem ter recursos especiais para acelerar esse passo;
  • Rasterization: Transforma todos os dados em fragmentos. Cada fragmento é um quadrado que corresponde a pixels no framebuffer. Padrões de linhas e polígonos, largura da linha, tamanho do ponto, shading, calculos de cobertura e anti-aliasing são todos levados em conta durante essa fase. Cor e valores de profundidade são considerados para cada fragmento;
  • Operações sobre fragmentos (Fragment Operations): Finalmente, operações finais são aplicadas aos fragmentos, tais como recortes, operações de máscaras de bits (como blending) são aplicadas. Então, os pixels são finalmente calculados e são encaminhados para desenho.

Outras bibliotecas relacionadas à OpenGL

A OpenGL fornece um conjunto poderoso de comandos, mas restrito apenas ao desenho. Várias bibliotecas existem para facilitar a manipulação de outros aspectos da aplicação, como as seguintes:

  • OpenGL Utility Library (GLU): Fornece diversas funções para auxiliar na montagem de matrizes de visualização e projeção, desenho de superfícies e imagens 3D. Essa biblioteca é fornecida juntamente com as implementações da OpenGL e todas as rotinas dessa biblioteca tem o prefixo glu.
  • Cada ambiente de janelas tem uma biblioteca de extensão da OpenGL. Por exemplo, o sistema X possui o glx, enquanto o Windows fornece a extensão wgl;
  • OpenGL Utility Toolkit (GLUT): É um toolkit que abstrai o sistema de janelas, fornecendo uma interface simples para a criação de uma aplicação OpenGL. É uma alternativa mais simples e limtada do que a SDL para fazer aplicações OpenGL;

Outras características importantes

  1. A OpenGL trabalha com a medida de ângulos em graus e não em radianos, como ocorre com a maioria das linguagens;
  2. Cada componente de cor na OpenGL é definido por um número de ponto flutuante, que varia de 0 até 1, e não um número inteiro de 0 até 255;
  3. As coordenadas gráficas padrão na OpenGL seguem o eixo cartesiano. Assim, o número da linha é decrescente, e não crescente;
  4. As matrizes são calculadas com base nas colunas, e não nas linhas, como normalmente aprendemos nas aulas de matemática. Isso também significa que multiplicação de matrizes devem ocorrer na ordem inversa da normal;
  5. Rotações de ângulos também são feitas da direita para esquerda, e não o contrário;
  6. A OpenGL não foi feita exclusivamente para jogos. Outras aplicações como CADs, 3D Studio, Blender também são usados pela engenharia e pelo cinema.

Veja também

Consulte também o seguinte material, onde partes desse artigo foram baseados:

Também recomendo o livro Beginning OpenGL Game Programming, de Dave Astle e Kevin Hawkings. Esse artigo também foi publicado por mim na wikipedia em português (o que estava lá estava muitíssimo incompleto).


Comentários (6)
  • gokernel
    avatar

    Bom ... curti a história sobre o OpenGL.

    gokernel
    gokernel@hotmail.com

  • Patrick Bassut
    avatar

    Valeu, me deu inicio ao OpenGL.
    rsrs, Agradeço

    Gostei da "historinha" também.

  • Vinícius Godoy de Mendonça
    avatar

    Obrigado pessoal. :)

  • Fabiano Vasconcelos  - Dúvidas sobre C++, OpenGL, 2D^3D, geração de terre
    avatar

    Bem, já que o fórum ainda não foi implementado, vou estorvar por aqui mesmo, ok? :woohoo:

    Olá, pessoas!

    Aí vão algumas perguntas para a galera do Ponto V (Brunão, Vinny e Cia. Ltda.):

    1. Quem se propõe a fazer um jogo 2D em C++ e OpenGL mas tem medo de se meter num jogo 3D tem razão por achar que o jogo 3D dá muito mais trabalho, demanda muito mais estudo e mais tempo, sendo, portanto, o jogo 2D mais simples ou não tem razão, visto que na implementação do 2D para o 3D as mudanças no código são poucas, quase não precisa acrescentar código, o tempo de codificação não aumenta assim tão consideravelmente e você só estuda umas coisinhas a mais? Se alguém tiver alguma opinião intermediária a estas duas, favor postar.

    2. Lembram do clássico River Raid? Pois aquele cenário é renderizado em tempo real. Como a semente é sempre a mesma, sempre saí o mesmo cenário. Fazer algo parecido em 2D ou 3D é muito difícil? É mais fácil construir um cenário fixo, passo a passo, já pré-definido e salvo em uma biblioteca?

    3. Geração de terreno é coisa de expert? O que vocês me dizem de um iniciante que se mete a gerar terreno randomicamente?

    Se estiverem curiosos pra saber do que eu estou falando, qual é o projeto, acessem:

    http://riverassault.jent.com.br
    http://riverassault.jent.com.br/group

    Obrigado pelas respostas, galera!

  • Vinícius Godoy de Mendonça
    avatar

    Discordo. As mudanças não são poucas não. Exige entender mais matemática, inclusive, mudar a forma de pensar sobre ela. Todos os algorítmos físicos são mais complicados. Claro, se você usar engine para tudo, a vida vai ficar muito mais fácil, mas ainda assim, exige bem mais conhecimento que um jogo 2D.

    Aliás, não só em termos de programação. Para a arte, você deixa de usar imagens para usar modelos 3D. Existe toda uma nova nomenclatura sobre modelo, textura, prefab, bones. Há consideravelmente menos material pronto na internet.

    Não que um iniciante seja incapaz, só vai ter muito mais trabalho. Mas muitos conceitos, como o do game loop, controle de tempo, tratamento de eventos, movimentação vetorial, IA e física, são mais facilmente entendidos se você começar em 2D.

    A recomendação geral é começar em 2D, pois você consegue estudar obtendo mais resultados. Muitos começam direto no 3D e abandonam o projeto em pouco meses, desestimulados.

    Agora, se você é daqueles que pode se meter num projeto por meses, ou até anos a fio, sem se preocupar em grandes resultados (e a maioria das pessoas não é assim), vai fundo.

    E, detalhe, você não seria o primeiro iniciante a conseguir uma façanha dessas, basta olhar o status do projeto Billy Oposto.

  • Bruno Crivelari Sanches
    avatar

    1 - No 2d praticamente toda matemática é a matematica que você aprende na escola, no 3d a conversa muda. Tem que se entender bem de matemática vetorial e matrizes. A principio no 2d basta aplicar os conhecimentos da escola e pronto, sem falar que muita coisa é bem intuitiva, já no 3d de inicio não é tão intuitivo assim.

    Saindo da matemática, todo o resto complica. Para gerar um cenário é bem mais complicado em 3d do que em 2d. Um modelo animado então. Se você não vai usar motor, então vai se complicar mais ainda, pois trabalhar com uma GPU é muito mais complexo do que renderizar gráficos 2d, mesmo usando OpenGL ou Direct3d para ambos.

    O " quase não acrescentar" código não consigo imaginar como, muda tudo.

    2 - Inicialmente é mais fácil fazer um cenário fixo.

    3 - Gerar um terreno é simples, gerar um terreno bonito requer um bocado de paciência para ajustar os parâmetros.

    T+

Escrever um comentário
Your Contact Details:
Gravatar enabled
Comentário:
[b] [i] [u] [url] [quote] [code] [img]   
:angry::0:confused::cheer:B):evil::silly::dry::lol::kiss::D:pinch::(:shock:
:X:side::):P:unsure::woohoo::huh::whistle:;):S:!::?::idea::arrow:
Security
Por favor coloque o código anti-spam que você lê na imagem.
LAST_UPDATED2  

Busca

Linguagens

Twitter