Desenhando pontos

6 01 2008

No artigo anterior, vimos as três principais formas básicas do OpenGL: pontos, linhas e polígonos. Também vimos os comandos com primitivas que permitem desenhar essas formas.

Neste artigo, vamos analisar em detalhes mais comandos para lidar com a primeira e mais fundamental forma básica, os pontos.

Desenhando pontos

Como visto no artigo anterior, é possível desenhar um ou mais pontos usando a primitiva GL_POINTS:


glBegin(GL_POINTS)
    glVertex3f(0.0, 0.0, 0.0);
    glVertex3f(0.0, 0.5, 0.0);
glEnd();

Usando GL_POINTS, cada vértice é desenhado como um ponto independente.
Alterando o tamanho de um ponto

Para alterar o tamanho de um ponto, você usa a função void glPointSize(GLFloat size), que permite especificar quadrado de tamanho size por size, que será centralizado na coordenada de vértice especificada. O tamanho real que o ponto será desenhado não depende da distância em que o ponto está em relação ao observador. Infelizmente, a função glPointSize deve ser usada fora dos blocos glBegin e glEnd.

O menor e o maior tamanho de ponto possível varia de implementação para implementação, mas pode ser questionado usando a função glGetFloatv com a constante GL_POINT_SIZE_RANGE, que retorna dois números de ponto flutuante. Da mesma forma, podemos questionar o tamanho atual do ponto usando a constante GL_POINT_SIZE. Se o anti-alias estiver desligado, o valor de retorno dessa função será arrendondado para o valor inteiro mais próximo, com um mínimo de 1, que indica o tamanho lado do ponto em pixels. Por exemplo:


GLfloat pointRange[2];
GLfloat actualPointSize;

glGetFloatv(GL_POINT_SIZE_RANGE, pointRange);
glGetFloatv(GL_POINT_SIZE, &actualPointSize);

GLfloat minPointSize = pointRange[0];
GLfloat maxPointSize = pointRange[1];

Pontos com suavização de serrilhado (antialiasing)
Simplesmente desenhar pontos uns sobre os outros pode deixar a imagem serrilhada, o que não é um efeito bonito de ser observado. Uma das capacidades do OpenGL é suavizar os pontos, de modo que pareçam circulares e que suas cores se misturem de maneira contínua umas com as outras. Embora isso tenha um custo computacional, o efeito final é muito mais bonito de ser observado.Você pode ativar ou desativar a suavização usando a constante GL_POINT_SMOOTH. Quanto a suavização está ligada, o tamanho do ponto não mais se refera a um lado, mas ao diâmetro de uma circunferência, centralizada no vértice especificado. Além disso, o tamanho poderá variar de maneira contínua e, como consequência, o tamanho de um ponto não será necessariamente um número inteiro.A variação entre o tamanho de um ponto e outro é chamada de granularidade. Assim, com a suavização desligada, a granularidade entre os pontos é igual a 1, ou seja, varia de tamanho de 1 em 1 pixel. A granularidade com a suavização ligada varia de hardware para hardware, mas pode ser questionada usando a constante GL_POINT_SIZE_GRANULARITY.Para suavização funcionar, também é necessário ativar a transparência, usando a capacidade GL_BLEND. Transparência é um tema amplo, e será discutido em artigos futuros.

Variando o tamanho do ponto de acordo com a distância

É possível fazer com o tamanho do ponto varie de acordo com a distância usando a função glPointParameter, presente nas extensões do OpenGL e promovida ao núcleo na versão 1.4. O uso dessa função, no entanto, não é trivial e está fora do escopo desse artigo. Para ver em detalhe como usar as extensões, leia esse artigo (em inglês).

A função glPointParameter é muito útil em simuladores de partículas, por exemplo. Ela possui os seguintes parâmetros:

  • GL_POINT_SIZE_MIN: Define o valor mínimo que o OpenGL fará a escala do ponto;
  • GL_POINT_SIZE_MAX: Define o valor máximo para o qual o OpenGL fará a escala do ponto;
  • GL_POINT_DISTANCE_ATTENUATION: Recebe um array de 3 floats, que define o fator de atenuação. O fator é dado por 1/[a + b*d + c*(d*d)], onde d é a distância do ponto ao olho. A raiz quadrada desse fator é multiplicada pelo tamanho, para obter o tamanho final do ponto. Por padrão, o valor de a, b e c é 1,0,0, o que representa nenhuma atenuação;
  • GL_POINT_FADE_THRESHOLD: Representa um tamanho a partir do qual o OpenGL vai passar a aumentar a transparência do ponto, a medida que ele se torne mais distante. Isso permite que o ponto desapareça gradualmente, a medida que fica mais distante.

Um exemplo

Preparei um exemplo que desenha 30 pontos na tela, de tamanhos de 1 até 15, com tamanhos variando de 0.5 em 0.5. O programa faz esse desenho 2 vezes, uma delas sem suavizar o serrilhado e outra com a suavização.

Repare que quando a suavização é ligada, os pontos assumem uma forma arredondada e que o desenho passa a variar para todos os pontos. Sem a suavização, os pontos são quadrados e não há diferença no desenho de um ponto de tamanho N e outro de tamanho N e meio. Veja o screenshot do exemplo abaixo:

O exemplo pode ser baixado aqui.


Ações

Informações

Deixe um comentário