Programação com OpenGL/Modern OpenGL Tutorial 06: diferenças entre revisões

[edição não verificada][edição não verificada]
Conteúdo apagado Conteúdo adicionado
Linha 56:
 
== Coordenadas da textura ==
 
Agora nós precisamos dizer onde cada vertex será localizada em nossa textura.
Para isto, vamos substituir o atributo <code>v_color</code> pelo vertex shader com um <code>texcoord</code>:
 
GLint attribute_coord3d, attribute_v_color''', attribute_texcoord''';
 
<source lang="c">
/* init_resources */
attribute_name = "texcoord";
attribute_texcoord = glGetAttribLocation(program, attribute_name);
if (attribute_texcoord == -1) {
fprintf(stderr, "Could not bind attribute %s\n", attribute_name);
return 0;
}
</source>
 
Agora, que parte da textura nós mapearemos, para dizer, no canto superior esquerdo da face da frente? Bem isto depende:
* Para a face frontal: o canto superior esquerdo da nossa textura
* Para o topo da face: o canto inferior-esquerdo da nossa textura
Nós vemos que múltiplos pontos da textura será anexada em algumas vértices, O vertex shader não será capaz de decidir qual deve ser escolhido.
 
Assim nós precisamos reescrever o cubo usando 4 vértices por face, sem reutilizar as vértices.
 
Para começar enfim, vamos apenas trabalhar com a face frontal. Facil! nós apenas teremos na tela os 2 primeiros triângulos (as 6 primeiras vértices):
<source lang="c">
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
</source>
 
Assim, as coordenadas da nossa textura estarão entre [0, 1], com o eixo x da esquerda para direita, e o eixo y de baixo para cima:
<source lang="c">
/* init_resources */
GLfloat cube_texcoords[] = {
// front
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
};
glGenBuffers(1, &vbo_cube_texcoords);
glBindBuffer(GL_ARRAY_BUFFER, vbo_cube_texcoords);
glBufferData(GL_ARRAY_BUFFER, sizeof(cube_texcoords), cube_texcoords, GL_STATIC_DRAW);
</source>
<source lang="c">
/* onDisplay */
glEnableVertexAttribArray(attribute_texcoord);
glBindBuffer(GL_ARRAY_BUFFER, vbo_cube_texcoords);
glVertexAttribPointer(
attribute_texcoord, // atributos
2, // numero de elementos por vértices, que é (x,y)
GL_FLOAT, // o tipo de cada elemento
GL_FALSE, // como o valor está
0, // sem dados extras em cada posição
0 // deslocamento do primeiro elemento
);
</source>
 
Vertex shader:
<source lang="glsl">
attribute vec3 coord3d;
attribute vec2 texcoord;
varying vec2 f_texcoord;
uniform mat4 mvp;
 
void main(void) {
gl_Position = mvp * vec4(coord3d, 1.0);
f_texcoord = texcoord;
}
</source>
 
Fragment shader:
<source lang="glsl">
varying vec2 f_texcoord;
uniform sampler2D mytexture;
 
void main(void) {
gl_FragColor = texture2D(mytexture, f_texcoord);
}
</source>
 
[[File:OpenGL_Tutorial_Texture_Flipped.png|thumb|Something is wrong...]]
Mas o que houve? Nossa textura está de cabeça para baixo!
 
Na convenção do OpenGL (começando no canto inferior esquerdo) é diferente das aplicações em 2D (começo no canto superior esquerdo).
Para corrigir isto podemos:
* Ler as linhas do pixel de baixo para cima
* Trocar as linhas do pixel
* Trocar as coordenadas Y da textura
 
A maior parte das bibliotecas gráficas retornam os array dos pixel como na convenção 2D. Porem o [http://openil.sourceforge.net/tuts/tut_10/index.html DevIL] é uma opção que mantém a origem como conhecemos. Como alternativa, temos alguns formatos como BMP e TGA que guardar as linhas do pixel de baixo para cima nativamente (o que pode explicar a certa popularidade que pesa para o TGA entre os desenvolvedores 3D), muito util quando se escrever um carregador próprio para ele.
 
Trocando as linhas do pixel podemos terminar o código C que rodaremos, se o seu programa está em linguagem de nível alto como o Python isto pode ser feito apenas em uma linha. A desvantagem é que o carregamento da textura será mais lento por causa dos passos extras.
 
Revertendo a coordenada da textura é um meio mais fácil para nós, podemos fazer isto no fragment shader:
<source lang="glsl">
void main(void) {
vec2 flipped_texcoord = vec2(f_texcoord.x, 1.0 - f_texcoord.y);
gl_FragColor = texture2D(mytexture, flipped_texcoord);
}
</source>
 
Certo, tecnicamente nós poderíamos escrever as coordenadas da textura em outra direçõe logo de cara - mas outros aplicativos 3D costumam trabalhar como nós descrevemos.
 
== Um cubo completo ==