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

[edição verificada][revisão pendente]
Conteúdo apagado Conteúdo adicionado
Abacaxi (discussão | contribs)
Sem resumo de edição
m <source> -> <syntaxhighlight> (phab:T237267)
 
Linha 18:
 
 
<sourcesyntaxhighlight lang="c">
GLfloat cube_vertices[] = {
// front
Linha 31:
-1.0, 1.0, -1.0,
};
</syntaxhighlight>
</source>
 
Para algo melhor que um massa preta, vamos então definir algumas cores:
<sourcesyntaxhighlight lang="c">
GLfloat cube_colors[] = {
// Cores de frente
Linha 47:
1.0, 1.0, 1.0,
};
</syntaxhighlight>
</source>
 
Não esqueça do global buffer handles(manipuladores globais do buffer):
<sourcesyntaxhighlight lang="cpp">
GLuint vbo_cube_vertices, vbo_cube_colors;
</syntaxhighlight>
</source>
 
== Elementos - Index Buffer Objects (IBO) ==
Linha 62:
 
É melhor especificar todas as faces de modo similar, em modo anti-horário, porque isto será importante para o mapeamento de textura(veremos no próximo tutorial) e luz.(assim um triângulo normal precisam apontar para o caminho certo)
<sourcesyntaxhighlight lang="c">
/* Global */
GLuint ibo_cube_elements;
</syntaxhighlight>
</source>
<sourcesyntaxhighlight lang="cpp">
/* init_resources */
GLushort cube_elements[] = {
Linha 92:
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(cube_elements), cube_elements, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
</syntaxhighlight>
</source>
 
Note que usamos um buffer object denovo, mas com <code>GL_ELEMENT_ARRAY_BUFFER</code> em vez <code>GL_ARRAY_BUFFER</code>.
 
Nós vamos chamar o OpenGL para desenhar nosso cubo em <code>onDisplay</code>
<sourcesyntaxhighlight lang="c">
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_cube_elements);
int size; glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &size);
glDrawElements(GL_TRIANGLES, size/sizeof(GLushort), GL_UNSIGNED_SHORT, 0);
</syntaxhighlight>
</source>
 
Nós usamos <code>glGetBufferParameteriv</code> para pegar o tamanho do buffer. deste jeito, nós não precisamos declarar <code>cube_elements</code>
 
== Ativando profundidade ==
<sourcesyntaxhighlight lang="c">
glEnable(GL_DEPTH_TEST);
//glDepthFunc(GL_LESS);
</syntaxhighlight>
</source>
 
glClear(GL_COLOR_BUFFER_BIT'''|GL_DEPTH_BUFFER_BIT''');
Linha 136:
 
Modelo(Model): Vamos colocar nosso cubo um pouco em segundo plano, então não misturaremos com a câmera:
<sourcesyntaxhighlight lang="cpp">
glm::mat4 model = glm::translate(glm::mat4(1.0f), glm::vec3(0.0, 0.0, -4.0));
</syntaxhighlight>
</source>
Visualização(View): O GLM tem uma ré-implementação do [http://www.opengl.org/sdk/docs/man/xhtml/gluLookAt.xml gluLookAt(eye, center, up)]. O eye é a posição da camera, o center é onde a camera é apontada, e o up é o topo da camera (no caso é inclinado). Vamos centralizar nosso objeto um pouco acima, com a camera reta:
<sourcesyntaxhighlight lang="cpp">
glm::mat4 view = glm::lookAt(glm::vec3(0.0, 2.0, 0.0), glm::vec3(0.0, 0.0, -4.0), glm::vec3(0.0, 1.0, 0.0));
</syntaxhighlight>
</source>
 
Projeção(Projection): O GLM também possui um re-implementação do [http://www.opengl.org/sdk/docs/man/xhtml/gluPerspective.xml gluPerspective(fovy, aspect, zNear, zFar)].
fovy é o angulo da lente, aspect é o aspecto da tela (largura/altura), zNear e ZFar são os limites da visualização aérea (min/max profundidade), ambos positivo, zNear é um valor pequeno e diferente de zero. Nós precisamos ver nosso quadrado, então usuaremos 10 para zFar.
<sourcesyntaxhighlight lang="cpp">
glm::mat4 projection = glm::perspective(45.0f, 1.0f*screen_width/screen_height, 0.1f, 10.0f);
</syntaxhighlight>
</source>
 
O <code>screen_width</code> e <code>screen_height</code> serão uma nova variável global que definirá o tamanho da janela:
<sourcesyntaxhighlight lang="cpp">
/* global */
int screen_width=800, screen_height=600;
</syntaxhighlight>
</source>
<sourcesyntaxhighlight lang="cpp">
/* main */
glutInitWindowSize(screen_width, screen_height);
</syntaxhighlight>
</source>
 
 
Resultado:
<sourcesyntaxhighlight lang="cpp">
glm::mat4 mvp = projection * view * model;
</syntaxhighlight>
</source>
 
Poderemos passar ele para o shader:
<sourcesyntaxhighlight lang="cpp">
/* Global */
#include <glm/gtc/type_ptr.hpp>
GLint uniform_mvp;
</syntaxhighlight>
</source>
<sourcesyntaxhighlight lang="cpp">
/* init_resources() */
const char* uniform_name;
Linha 181:
return 0;
}
</syntaxhighlight>
</source>
<sourcesyntaxhighlight lang="cpp">
/* onIdle() */
glUniformMatrix4fv(uniform_mvp, 1, GL_FALSE, glm::value_ptr(mvp));
</syntaxhighlight>
</source>
 
E no shader:
<sourcesyntaxhighlight lang="glsl">
uniform mat4 mvp;
void main(void) {
gl_Position = mvp * vec4(coord3d, 1.0);
[...]
</syntaxhighlight>
</source>
 
== Animação ==
Linha 201:
 
Para rodar o cubo, vamos colocar no <code>onIdle</code>:
<sourcesyntaxhighlight lang="cpp">
float angle = glutGet(GLUT_ELAPSED_TIME) / 1000.0 * 45; // 45° por segundos
glm::vec3 axis_y(0.0, 1.0, 0.0);
Linha 207:
[...]
glm::mat4 mvp = projection * view * model * anim;
</syntaxhighlight>
</source>
 
Então fizemos uma tradicional cubo com voo rotativo!
Linha 215:
Para suportar o redimensionamento de janela do GLUT, você pode usar a função <code>glutReshapeFunc</code>:
 
<sourcesyntaxhighlight lang="cpp">
void onReshape(int width, int height) {
screen_width = width;
Linha 221:
glViewport(0, 0, screen_width, screen_height);
}
</syntaxhighlight>
</source>
<sourcesyntaxhighlight lang="cpp">
/* main */
glutReshapeFunc(onReshape);
</syntaxhighlight>
</source>
 
Nota: A cena tende a pular quando é redimensionada - Eu não consigui descobrir de onde vem isto.