![]() |
|
No artigo anterior, vimos como alterar o tamanho de pontos a adicionar a eles o efeito de suavização. Neste artigo, iremos explorar outras propriedades da segunda forma básica: as linhas.
Desenhando linhas
Linhas são definidas por 2 vértices. Você pode desenhar uma série de linhas não conectadas usando a primitiva GL_LINES. Com essa primitiva, a cada 2 vértices desenhados, uma nova linha é criada:
glBegin(GL_LINES); glVertex3f(-1.0f, -1.0f, -1.0f); glVertex3f(1.0f,1.0f,1.0f); glEnd();
Desenhar uma série de linhas conectadas dessa forma é um tanto tedioso. A cada nova linha, o vértice da última linha teria que ser novamente utilizado como vértice inicial. Para contornar esse problema, foi criado o comando GL_LINE_STRIP. Nesse comando, os dois primeiros vértices representam uma linha, exatamente como no caso do GL_LINES. Porém, cada vértice adicional define uma nova linha, com início no vértice anteriormente desenhado. O que poupa muito trabalho:
glBegin(GL_LINE_STRIP); glVertex2f(-1.0f, -1.0f); glVertex2f(0.5f, 1.0f); glVertex2f(-1.0f, 1.0f); glEnd();
Entretanto, se quiséssemos traçar um polígono fechado através de linhas, teríamos novamente que repetir o primeiro ponto. Para evitar isso, usamos o comando GL_LINE_LOOP, então, o primeiro ponto de nossa seqüência de linhas será automaticamente conectado ao último.
Alterando a largura das linhas
Para alterar a largura de uma linha, você usa a função void glLineWidth(GLFloat width), que recebe como parâmetro um valor que deve ser maior do que zero. Por padrão a largura da linha é 1. Analogamente aos pontos, só haverá diferença de tamanho para linhas não inteiras caso a suavização esteja desligada. O maior e o menor tamanho de linhas possíveis vai depender do hardware gráfico e pode ser questionado usando a função glGetFloatv com a constante GL_LINE_WIDTH_RANGE, que retorna dois números de ponto flutuante.
Da mesma forma, podemos usar a função glGetFloatv e a constante GL_LINE_WIDTH para obter a largura atual da linha. A largura de uma linha sem suavização não será medida de maneira perpendicular a linha. Ela será medida levando-se em conta só o eixo x ou y, dependendo da inclinação da linha. Já no caso da linha suavizada, a largura será calculada de acordo com o retângulo desenhado, centralizado na linha.
Veja um exemplo do uso dessas funções:
GLfloat lineRange[2]; GLfloat actualLineWidth; glGetFloatv(GL_LINE_WIDTH_RANGE, lineRange); glGetFloatv(GL_LINE_WIDTH, &actualLineWidth); GLfloat minLineWidth = pointRange[0]; GLfloat maxLineWidth = pointRange[1];
Muito similar ao que fizemos com pontos, não?
Linhas com suavização de serrilhado (anti-aliasing)
A suavização com linhas funciona basicamente da mesma maneira do que a suavização com pontos. Basta ligar ou desligar a capacidade GL_LINE_SMOOTH usando glEnable/gDisable.
A granularidade do aumento da largura da linha também pode ser obtido com a função glGetFloatv, associada a constante GL_LINE_WIDTH_GRANULARITY.
Para que a suavização funcione, também é necessário que você use a técnica de blending.
Padrões de tracejado
Você também pode especificar padrões de tracejado para sua linha, seja pontinhos ou traços. Para fazer isso, você ativa a capacidade GL_LINE_STIPPLE, usando a boa e velha glEnable. Depois, você usa a função:
void glLineStipple(GLint factor, GLushort pattern);
Para definir qual padrão exatamente você quer aplicado à linha. O parâmetro do padrão representa 16 bits que definem onde a linha será pintada. Por exemplo, o padrão 0x0F0F representa em binário: 00000000111111110000000011111111. Agora, simplesmente imagine uma linha onde tem 1s e nenhuma onde tem zeros. Na verdade, o padrão é desenhado ao contrário, do último 1 até o primeiro.
Cada bit será considerado um número de vezes igual ao fator. Então um padrão que comece com:
01110111 será encarado como 000111111111000111111111 para um fator igual a 3. Vejamos graficamente alguns exemplos, retirados do próprio manual da OpenGL:
Lembre-se de encarar cada um desses valores como números binários.
Um exemplo
Preparei um exemplo que desenha dois conjuntos de linhas, com larguras e padrões diferentes. O conjunto da esquerda e da direita são iguais, mas o da direita usa suavização. O screenshot está abaixo:
O exemplo pode ser baixado aqui.