# Programação com OpenGL/Modern OpenGL Tutorial 03
## Attributes: Passando informações adicionais de vértices

Será necessário mais algumas coordenadas em nosso programa. Por exemplo: cores. Vamos passar cores em RGB para o OpenGL.
Nós passaremos as coordenadas usando um attribute, assim iremos colocar novos atributos para as cores. Vamos modificar nossas variáveis globais:
e nosso init_resources:
Agora em nosso onDisplay, nós iremos passar 1(uma) cor RGB para cada 3 vértices. vou escolher amarelo, azul e vermelho, mas fique a vontade para escolher suas cores favoritas :)
Vamos chamar o OpenGL apenas para completar o atributo, e terminar nossa função:
Por ultimo, declararemos isto ao nosso vertex shader:
Neste ponto, ao rodarmos o programa, teremos isto:
Isto acontece porque não usamos o v_color ainda.
O problema é: queremos cor no fragment shader, não no vertex shader! Vamos ver agora como fazer...

## Varyings: Passando informações do Vertex Shader para o Fragment Shader

Em vez de usar um atributo, vamos usar uma variável varying. Assim:
* Uma variável output(saida) para o vertex shader
* Um variavel input(entrada) para o fragment shader
* Isto tudo interpolado.
assim teremos um canal de comunicação entre os dois shader. para entender porque ele é interpolado, vamos ao seguinte exemplo.
Nós vamos declarar nossa nova varying, dizendo f_color, no
em triangle.v.glsl:
em triangle.f.glsl:
(Nota: se estamos usando a GLES2, verifique a seção de portabilidade abaixo.)
Vamos ver o resultado:
nossa, temos realmente mais de três cores!
O OpenGL interpola os valores dos vertices em cada pixel. Isto explica o nome varying(algo como variando): ele varia para cada vértice(vertex), e depois varia mais em cada fragmento(fragment).
Nós não podemos declarar um varying no código C - que não tem uma interface que suporte varying em C.

## Intercalando coordenadas e cores

Para entender melhor a função glVertexAttribPointer, vamos misturar vários atributos em uma única array(ordenação):
No glVertexAttribPinter o 5 elemento é uma stride, para dizer ao OpenGL quando cada atributo será configurado - em nosso caso 5 floats:
Ele funciona da mesma forma!
Note que para cores. nós começamos no 3º elemento(2 * sizeof(GLfloat) da array, onde a primeira cor que é o offset(deslocamento) do primeiro elemento.
Porque (GLvoid*)? Vimos que, em algumas versões do OpenGL, era possivel passar um ponteiro para array C diretamente(em vez de buffer de objeto). Isto agora é obsoleto, mas o prototipo glVertexAttribPointer manteve inalterado, por isto passamos como se fosse um ponteiro, mas passamos realmente um offset.
Um alternativa por esporte:
Note que usamos offsetof para especificar a primeira cor do offset.

## Uniforms: Passando a informação global

O Oposto de uma variável attribute é as variáveis uniform: Elas são as mesmas para todas as vértices. Note que podemos mudar-los em uma forma de base regular pelo código C - mas cada vez que um conjunto de vértices é mostrada na tela, a uniform será constante.
Vamos dizer que nós queremos definir a transparência global do triângulo pelo código C. tal qual acontece com os attributes, nós precisamos declaro isto. em uma global no código C:
Depois de declararmos isto no código C (ainda após a linkagem do programa)
Note: Poderiamos até atingir um array especifica de elementos no código de shader com uniform_name, e.g. "my_array[1]"!
Além disto, para o uniform, nó também definiremos explicitamente o valor da non-varying. Vamos requisitar, em onDisplay, que o triangulo deve ser um pouco opaco:
Agora nós podemos usar esta variável em nosso fragment shader:
Nota: se você não usar uniform em seus código, o glGetUniformLocation não vai enxergar nada, e vai falhar.

## Portando para OpenGL ES 2

Na seção anterior, foi mencionado que o GLES2 precisa de precision hints, ou seja sugestões de precisão, esses hints fala para o OpenGL qual é a precisão que queremos de nossos dados. Um precisão pode ser:
* lowp
* mediump
* highp
Por exemplo, o lowp pode normalmente ser usado para cores, e recomendados usar highp para as vértices.
Nós podemos especificar a precisão para cada variável.
ou, nós podemos declarar a precisão padrão:
Infelizmente os precision hints não funciona no OpenGL 2.1 tradicional, então nós vamos incluir apenas no GLES2.
O GLSL inclui um preprocessador(preprocessor), similar aos precessadores do C, nós podemos usar directivas como #define ou #ifdef
Apenas o fragment shader, exige que seja especificado uma precisão para os floats. A precisão foi especificada como highp para o vertex shader. para o Fragment shader, o highp não deve estar disponivel, que pode ser experimentado usado o macro GL_FRAGMENT_PRECISION_HIGH
Nós já pré-especificamos um directiva de processamento para o macro através da função utilitária create_shader:
Agora podemos melhorar nosso carregamento de shader para isto definiremos um precisão padrão no GLES2, e ignoraremos o identificador de precisão no OpenGL 2.1(assim ainda podemos definir um precisão para uma variável especifica se precisarmos):
Lembrando que o compilador GLSL poderá contar as linhas pré-especificados enquanto mostra mensagens de erro, Ajustando a #line 0 infelizmente não reiniciara o contagem de linha do compilador

## Atualizando a Tela

Agora seria bem legal se a transparência pudesse continuar variando e voltando. Para fazer isto,
* Precisamos verificar o numero de segundo desde que o usuário iniciou o aplicativo; o glutGet(GLUT_ELAPSED_TIME)/1000 dá que
* Aplicando um função aritmética sin em nossa(a função sin volta ao primeiro entre -1 and +1 a cada 2.PI=~6.28 unidades de tempo)
* Pergunte ao aplicativo que atualizará o triângulo(com novo valor de transparência); isto é o glutPostRedisplay
* O GLUT uma função ociosa "idle" que é chamada sempre que o GLUT não tem mais nada o que fazer. (ex. quando terminamos de mostrar o triângulo), nós podemos colocar nosso código lá.
No main, vamos declarar a função "idle", depois glutDisplayFunc(...):
Vamos adicionar a nova função ociosa.
também removeremos a chamada para glUniform1f da onDisplay
e por ultimo, nós vamos fazer uma declaração de um biblioteca aritmética do C.
no Makefile deixe assim:
Compile e Rode...
Temos nossa primeira animação!
É comum que uma implementação do OpenGL aguarde a atualização vertical da tela depois atualize o buffer da tela física = isto é chamado de vertical sync. Quem neste caso, o triângulo será renderizado aproximadamente 60 vez por segundo (60 FPS). se você desativar o vertical sync, o programa manterá atualizando o triangulo continuamente, resultado em um alto uso da CPU. Vamos nós encontrar denovo com o vertical sync, quando nós criarmos aplicativos com alteração de perspectiva.

## Referências

* ↑ É um pouco confuso tendo apenas um único exemplo nos diferentes conceitos de atributos e variantes. Vamos tentar procurar dois exemplos separados para uma melhor explicação.
* ↑ Cf. OpenGL ES Shading Language 1.0.17 Specification. Khronos.org (2009-05-12)., seção 4.5.3 Default Precision Qualifiers