Ponto V!

Home OpenGL Desenhando polígonos – Parte 1
Vinícius Godoy de Mendonça
Desenhando polígonos – Parte 1Imprimir
Escrito por Vinícius Godoy de Mendonça

Nos artigos anteriores, vimos pontos e linhas. Embora sejam interessantes, ainda estão longe de mostrar todo o poder que a OpenGL tem. A partir de agora, vemos como desenhar polígonos. Desenhar polígonos é um campo ainda mais vasto, pois é sobre polígonos que a OpenGL aplicará recursos como iluminação, mistura de cores, texturas, materiais, entre outras. Nesse artigo, e nos próximos da série “Desenhando polígonos”, veremos ainda o básico sobre o desenho de polígonos, ainda de maneira muito similar ao que vimos até agora com linhas e pontos. Nos próximos, aprofundaremos em cada um dos outros recursos da OpenGL.

Polígonos e seus lados

Qualquer triângulo pode ser descrito por três pontos, que não estejam alinhados numa reta (não-colineares). Por se tratar apenas de três pontos, é praticamente impossível traçar um triângulo de maneira errada. Eles também definem um plano, sempre são polígonos convexos, são rapidamente desenhados pelo hardware, por isso, constituem a mais importante forma da OpenGL. Não se impressione se nos sites e nos materiais sobre OpenGL por aí, você encontrar verdadeiros fanáticos por triângulos. Por isso, iniciaremos a explicação sobre polígonos utilizando-os como exemplo.

O comando mais simples para se desenhar um triângulo é o GL_TRIANGLES. Você deve passar os três vértices para o triângulo recém formado. Veja no exemplo (as setas apenas ilustram a ordem de desenho dos pontos, não serão desenhadas):

triangulo

Os dois comandos geram exatamente o mesmo triângulo, certo? Errado. Uma das maiores diferenças entre os polígonos e as outras formas vistas até aqui é que polígonos tem lado. E a OpenGL define esse lado pela ordem em que os comandos de desenho são dados. Por padrão, se os pontos são desenhados em sentido anti-horário, a figura está virada de frente, se os pontos são desenhados em sentido horário, a figura está de costas. Lados diferentes podem ter cores diferentes, materiais diferentes, ou mesmo, pode-se pedir para a OpenGL não desenhar em absoluto um dos lados da figura! Impedir um dos lados de ser desenhado pode reduzir o tempo de desenho, e é útil especialmente em figuras tridimensionais fechadas, como um cubo, para que a OpenGL não desenhe os lados internos, por exemplo. Na figura acima, o primeiro desenho está de frente, e o segundo de costas.

Esse sentido é conhecido como “winding“. Você pode alterá-lo usando o comando glFrontFace e passando para ele a constante GL_CW para desenhar o lado da frente fornecendo comandos no sentido do relógio (CW se refere a clockwise, que é o sentido do relógio), ou então voltar ao padrão usando a constante GL_CCW (counterclockwise). Raramente é necessário usar essa função, já que normalmente não desenhamos figuras “no braço”, no futuro, veremos como carregar modelos prontos de programas como Blender.

Modos de desenho e culling

Nem sempre queremos desenhar os polígonos de maneira sólida. As vezes, é bom desenhar apenas as linhas dos polígonos para ganhar performance (quando estamos editando um cenário complexo, por exemplo), ou mesmo somente os seus pontos. Algumas vezes, como já comentado acima, podemos desejar não desenhar um dos lados totalmente.

A função glPolygonMode define exatamente isso. Ela recebe dois parâmetros, o primeiro refere-se a que lado da figura será afetado – que pode ser GL_FRONT, GL_BACK ou o prático GL_FRONT_AND_BACK. E o segundo, o modo de desenho em si, que pode ser um dos três:

  • GL_POINT: Produz o mesmo efeito de desenharmos usando a primitiva GL_POINTS. Apenas os vértices são desenhados na forma de pequenos pontinhos;
  • GL_LINE: Produz o mesmo efeito se tivéssemos desenhado usando a primitiva GL_LINE_LOOP. Apenas as linhas são desenhadas, sem qualquer preenchimento interno;
  • GL_FILL: É o estado padrão, desenha a figura com o interior preenchido. Somente através nesse modo é que poderemos aplicar suavização e, obviamente, cores, texturas e padrões.

E para eliminar totalmente o desenho de um dos lados do polígono? Para isso, habilitamos a capacidade GL_CULL_FACE usando a função glEnable. Automaticamente, a OpenGl iniciará a eliminação de um dos lados de tudo que for desenhado em seguida, até que um glDisable() dessa capacidade seja encontrado. E qual lado será eliminado? Para definir isso, usamos a a função glCullFace. A função aceita dois parâmetros GL_BACK (para eliminar o fundo) e GL_FRONT para eliminar a frente. A palavra”Cull” se refere a culling, que é justamente o processo de eliminação de partes desnecessárias do desenho.

Suavização de serrilhado (anti-aliasing)

Assim como os pontos e as linhas, também é possível aplicar suavização aos polígonos. Para fazer isso apenas habilitamos a capacidade GL_POLYGON_SMOOTH usando glEnable, como você provavelmente já havia deduzido. Como nos demais casos, podemos questionar se esse valor está ou não ligado usando essa mesma constante nas funções glGet e glIsEnabled.

É importante ressaltar que suavização em polígonos é um recurso caro. Use-o com cuidado e nunca deixe de avaliar bem o seu impacto na performance do seu código. Não é a toa que muitos jogos profissionais fornecem opções para que o usuário escolha se deseja ou não ligá-lo.

Para que a suavização funcione, também é necessário que você use a técnica de blending.

Cores

Exceto se estivermos produzindo um jogo sobre o primeiro volume de Sin City, precisaremos de cores além do preto e do branco. Vamos aprofundar um pouquinho mais no básico sobre cores, para poder desenhar nossos polígonos com alguma graça. No futuro, farei um artigo inteiro sobre o assunto.

Como já vimos brevemente no passado, um dos comandos para colorir na OpenGL é o glColor. Esse comando tem uma infinidade de assinaturas, que aceitam praticamente qualquer tipo de dado conhecido. O que é importante saber, é que o comando aceita os três tradicionais parâmetros de cor, verde, vermelho, azul, mas que cada canal é representado por um valor de ponto flutuante, que varia entre 0 (sem a cor) e 1 (totalmente ligada). Mesmo as funções que utilizam números inteiros e unsigned, mapeiam o menor valor aceito pela variável em questão para 0, e o maior valor para 1, aplicando a proporção nos demais valores.

Existe um motivo: a notação é diferente da maior parte das linguagens e ferramentas, porque as cores referem-se apenas a cor real do objeto. Essa cor ainda sofrerará transformações de acordo com as luzes (que também podem ser coloridas) e o material do objeto, com a possível presença de materiais transparentes em frente dele e de acordo com sua distância relativa do objeto com a câmera. Portanto, para a decepção do seu designer gráfico, não basta apenas conhecer a tabela Pantone para definir exatamente o que vai ou não aparecer na tela.

Os principais comandos de cor usados são os seguintes:

  • glColor3f – Define a cor em seus 3 componentes RGB, sendo 0 para ausência de cor e 1 para presença;
  • glColor3fv – Variação do comando acima, que aceita um array com os 3 componentes;
  • glColor4f e glColor4fv – Inclui além dos três componentes de cor, um componente de transparência (canal alfa);
  • glColor3ubv e glColor4ubv – Aceita vetores com os componentes em unsigned bytes. Assim, os componentes podem assumir valores 0 para o menor componente de cor, e 255 para o maior.

As cores são aplicadas por vértice. Se os vértices forem coloridos, a OpenGL fará a aproximação das cores. É por isso que com apenas três comandos de cor, geramos o triângulo super colorido dos primeiros exemplos. Lembram-se dele?

ogl1

Podemos desabilitar esse efeito através do comando glShadeModel() usando o parâmetro GL_FLAT. Assim o polígono assumirá apenas a primeira cor que lhe for atribuída e desprezando as outras. Ou, podemos retornar ao padrão através do parâmetro GL_SMOOTH.

Esses comandos de cor também podem ser usados para linhas e pontos.

Mais detalhes sobre as primitivas

Você deve estar lembrado que ao falarmos das primitivas da OpenGL, citamos também algumas que desenhavam múltiplos polígonos como GL_TRIANGLE_FAN, GL_TRIANGLE_STRIP e GL_QUAD_STRIP. Você pode estar se perguntando, como fica a questão do winding nesse caso? Como era de se esperar, a OpenGL manterá a face de todos os polígonos voltadas para o mesmo lado.

Além dessa garantia, é importante saber que esses comandos também promovem otimização do hardware do vídeo, e que triângulos são preferíveis a qualquer outra forma geométrica. De fato, muitos softwares para composição e formatos de modelos procuram inserir apenas triângulos em suas formas. Como é o caso do formato MD2, do Quake 2.

Próximos passos


Nos próximo artigo, veremos como aplicar padrões de desenho aos polígonos e como evitar o desenho de determinados vértices. Usando o conhecimento de hoje, procure fazer o seguinte exercício:

1. Construa um cubo, em três dimensões usando a primitiva GL_QUADS.
2. Deixe cada face do cubo de uma cor diferente, em um suave degradée (basta colocar 2 vértices num tom mais claro, e 2 num tom mais escuro);
3. Substitua a primitiva GL_QUADS por GL_TRIANGLES e tente construir o mesmo cubo;
4. Aplique culling para eliminar os lados não desenhados do cubo: Você pode ter surpresas aqui se o winding de seu cubo estiver errado.
5. Suavize o desenho do cubo;

Trabalharemos muito com esse cubo nos artigos futuros. Portanto, é bom você conhecê-lo bem.


Comentários (17)
  • Aluno relapso
    avatar

    Fera meu, tanto no pessoal quanto no profissional. Oh, loco! :lol:

    Estou acompanhando sua série de artigos, não vá parar no meio do caminho. Seu site é muito bom.

  • Vinícius Godoy de Mendonça  - Valeu!
    avatar

    Valeu. Pode deixar, tem muito artigo além desse. :)

  • daniela
    avatar

    ow td bom????

  • Jonathas Moises  - OpenGL Clipping
    avatar

    Olá galera do PontoV!

    Eu já me batí pela internet procurando uma solução e nada...

    A SDL nós podemos usar o SDL_Rects e SDL_BlitSurface com o rect que queremos, assim podemos mostrar no screen somente a parte que quizermos da surface.

    Eu estou tentando usar a SDL + OpenGL e não consigo fazer cliprects com OpenGL.

    Tentei com o glClipPlane() e nada, com glScissor() eu até conseguí alguma coisa, mas não sei se por erro no meu código o clipping fica errado.

    Por favor, alguem poderia me dar uma ajuda com isso?

  • sara  - legal
    avatar

    gostei pois ja precisei saber mais sobre os poligonos e achei muitas coisas interessantes sobre eles:os poligonos[/quote]

  • João  - Como desenho uma letra no plano?
    avatar

    Boa tarde, Vinícius.
    Eu gostaria de saber como faço para desenhar uma letra. Ex: a letra A, no plano cartesiano e representá-la através de uma função. Como faço? Você pode me ajudar?

  • Vinícius Godoy de Mendonça  - Carderno milimetrado
    avatar

    O jeito mais fácil de começar é desenhando uma letra num caderno milimetrado. O ideal é desenhar letras quadradas como o A maiúsculo.

    Então, bastará colocar números em cada linha e coluna dos quadradinhos e você já terá seu plano cartesiano.

  • nayara  - verdade
    avatar

    verdade eu di veis em quando tambens fasso isso thau thauuuuuuuuuuuuuuuuuuuu :woohoo:

  • kauane  - gostei
    avatar

    foi muito boa :silly:

  • nayara  - legal
    avatar

    adorei adoro muito bom acompanho todo dia em muitos bijossssssssssssssssssssssssssssssssssssssss B)

  • vitoria  - não achei o que eu queia
    avatar

    :arrow: :idea: ;) :evil: :X :silly: Não achei o que eu queria

  • WilliamLycan  - OpenGL
    avatar

    Olá Vinicius, primeiramente parabéns pelo site e pelos posts, está me ajudando muito mesmo :cheer: .

    Quando eu rodo o programa usando minha placa de vídeo (OpenGL 3.3) tudo funciona perfeitamente, mas quando uso o vídeo onboard (OpenGL 1.4) os polígonos são desenhados em apenas uma cor (vermelho) mesmo usando a função para definir a cor glColor3f(0,0,0)
    tem algum cap da OpenGL 1.4 que eu possa ligar ou desligar?
    Ahh ainda no aguardo do post, como importar modelos do Blender no projeto?
    Obrigado, abraço

  • Vinicius Godoy
    avatar

    Tente colocar a quantidade de bytes por pixel em no máximo 24. Algumas placas mais antigas não suportam 32 bits.

  • Anônimo  - bbb
    avatar

    o que tem a ver com poligono ?

  • Anônimo  - aevu
    avatar

    o que sao blits

  • vadia das cataratas  - que porra esse lixo
    avatar

    nossa q chato pesei que eu poderia fazer mass essa :X :evil: mas nao da esse lix :idea: :?: :?: :!: :arrow: :huh: :unsure: :side:

  • AILA  - CALMA
    avatar

    Nossa mina muita calma isso nao e lixo isso e pra aprender :cheer: :lol: :kiss: :kiss: :) falo antes q me chingue :idea: :confused: :confused:

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