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

[edição verificada][revisão pendente]
Conteúdo apagado Conteúdo adicionado
m <source> -> <syntaxhighlight> (phab:T237267)
 
Linha 52:
 
Nosso interpretador será limitado (sem suporte para múltiplos objetos, alternado os formatos dos vértices, polígonos, etc.), mas isto será suficiente para o que precisamos.
<sourcesyntaxhighlight lang="cpp">
void load_obj(const char* filename, vector<glm::vec4> &vertices, vector<glm::vec3> &normals, vector<GLushort> &elements) {
ifstream in(filename, ios::in);
Linha 85:
}
}
</syntaxhighlight>
</source>
Nós usaremos vectors C++ para simplificarmos o gerenciamento de memória(sem <code>malloc</code>)
Vamos passar argumentos por referencia, principalmente por que o acesso à ponteiro em vector fica horrível(<code>(*elements)[i]</code>)
 
Então podemos carregar o arquivo .obj assim:
<sourcesyntaxhighlight lang="cpp">
vector<glm::vec4> suzanne_vertices;
vector<glm::vec3> suzanne_normals;
Linha 96:
[...]
load_obj("suzanne.obj", suzanne_vertices, suzanne_normals, suzanne_elements);
</syntaxhighlight>
</source>
 
E passaremos para OpenGL usando:
<sourcesyntaxhighlight lang="cpp">
glEnableVertexAttribArray(attribute_v_coord);
// Descrevemos nossa array de vértices para o OpenGL (o formato não descoberto automaticamente)
Linha 125:
int size; glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &size);
glDrawElements(GL_TRIANGLES, size/sizeof(GLushort), GL_UNSIGNED_SHORT, 0);
</syntaxhighlight>
</source>
 
[[File:OpenGL Tutorial Suzanne rotating.png|thumb|Suzzane, em nosso aplicativo]]
E por ultimo, vamos ajustar nossa visualizaçao de acordo com o sistem de coordenada Y-is-top, e a camera voltada para Suzzane:
<sourcesyntaxhighlight lang="cpp">
glm::mat4 view = glm::lookAt(
glm::vec3(0.0, 2.0, 4.0), // olho
Linha 135:
glm::vec3(0.0, 1.0, 0.0)); // up
glm::mat4 projection = glm::perspective(45.0f, 1.0f*screen_width/screen_height, 0.1f, 100.0f);
</syntaxhighlight>
</source>
 
Eu enganei um pouco e implementei um modelo de iluminação de Gouraud, vamos melhorar aos poucos.
Linha 144:
 
Isto acontece se nós não compartilharmos as normals (e escolheu um rosto arbitrário quando calcularmos uma vertex' normal, como fizemos acima). Neste caso nós precisamos duplicar um vértice toda vez que for usado com uma normal diferente e depois recriando o array de elementos. Isto fará que demore mais tempo para carregar mas será mais rápido para o OpenGL processo a longo prazo. quanto menos vértices for enviado para OpenGL melhor. ou, como dizemos anteriormente, neste exemplo apenas duplicaremos as vértices uma única vez quando eles aparecem e nós podemos fazer sem a array de elementos.
<sourcesyntaxhighlight lang="cpp">
for (int i = 0; i < elements.size(); i++) {
vertices.push_back(shared_vertices[elements[i]]);
Linha 158:
}
}
</syntaxhighlight>
</source>
<sourcesyntaxhighlight lang="cpp">
glDrawArrays(GL_TRIANGLES, 0, suzanne_vertices.size());
</syntaxhighlight>
</source>
 
Com este ajuste, nós podemos ter uma flat-shading: a variável varying atualmente varia entre os vértices no fragment shader, por que as normal serão os mesmos para as 3 vértices do triângulo.
Linha 173:
 
[[File:OpenGL Tutorial Suzanne normals average.png|thumb|Normals calculadas]]
<sourcesyntaxhighlight lang="cpp">
mesh->normals.resize(mesh->vertices.size(), glm::vec3(0.0, 0.0, 0.0));
nb_seen.resize(mesh->vertices.size(), 0);
Linha 199:
}
}
</syntaxhighlight>
</source>
 
== Normals pré calculadas ==