Skip to content

Commit bcb1456

Browse files
committedApr 14, 2016
Tutorial OpenGL 08 - ASSIMP
Importación de modelos 3D en formatos como dae, obj, fbx, x, etc., con la biblioteca assimp.
1 parent 3b796a4 commit bcb1456

File tree

5 files changed

+314
-0
lines changed

5 files changed

+314
-0
lines changed
 

‎Tutorial-08/CMakeLists.txt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
file(COPY phong.vertex_shader phong.fragment_shader DESTINATION shaders)
2+
file(COPY cessna.assbin DESTINATION model)
3+
4+
set(ASSIMP_DIR $ENV{ASSIMP_DIR} CACHE PATH "Assimp Directory")
5+
6+
find_package(ASSIMP REQUIRED)
7+
8+
link_directories(${ASSIMP_LIBRARY_DIRS})
9+
include_directories(${ASSIMP_INCLUDE_DIRS})
10+
11+
add_executable( 08-Assimp assimp-model.cpp
12+
shaders/phong.vertex_shader
13+
shaders/phong.fragment_shader
14+
../common/openglwindow.hpp
15+
../common/openglshader.hpp )
16+
17+
target_link_libraries( 08-Assimp ${GRAPHIC_LIBS} ${ASSIMP_LIBRARIES})

‎Tutorial-08/assimp-model.cpp

Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
#include "OpenGLWindow.hpp"
2+
#include "OpenGLShader.hpp"
3+
4+
#include <glm\gtc\matrix_inverse.hpp>
5+
#include <glm\gtc\matrix_transform.hpp>
6+
#include <glm\gtc\type_ptr.hpp>
7+
8+
#include <string>
9+
#include <vector>
10+
#include <memory>
11+
12+
#include <assimp/Importer.hpp> // C++ importer interface
13+
#include <assimp/scene.h> // Output data structure
14+
#include <assimp/postprocess.h> // Post processing flags
15+
16+
using namespace std;
17+
18+
class Mesh {
19+
20+
public:
21+
Mesh(const aiMesh* mesh) {
22+
load(mesh);
23+
create();
24+
}
25+
26+
~Mesh() {
27+
glDeleteBuffers(4, buffer);
28+
glDeleteVertexArrays(1, &vao);
29+
}
30+
31+
// dibujar el mesh
32+
void draw() {
33+
glBindVertexArray(vao);
34+
glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, NULL);
35+
glBindVertexArray(0);
36+
};
37+
38+
// inicializar el mesh
39+
void init(const aiMesh* mesh) {
40+
load(mesh);
41+
create();
42+
};
43+
44+
private:
45+
vector<glm::vec3> vertex;
46+
vector<glm::vec3> normal;
47+
vector<glm::vec2> uv;
48+
vector<unsigned int> indices;
49+
50+
GLuint buffer[4];
51+
GLuint vao;
52+
53+
// obtener los datos de cada mesh
54+
void load(const aiMesh* mesh) {
55+
56+
vertex.reserve(mesh->mNumVertices);
57+
uv.reserve(mesh->mNumVertices);
58+
normal.reserve(mesh->mNumVertices);
59+
indices.reserve(3 * mesh->mNumFaces);
60+
61+
for (unsigned int i = 0; i < mesh->mNumVertices; i++) {
62+
// Obtener la posicion de cada vertice
63+
aiVector3D pos = mesh->mVertices[i];
64+
vertex.push_back(glm::vec3(pos.x, pos.y, pos.z));
65+
66+
// Obtener las coordenadas de textura
67+
if (mesh->HasTextureCoords(0)) {
68+
aiVector3D UVW = mesh->mTextureCoords[0][i];
69+
uv.push_back(glm::vec2(UVW.x, UVW.y));
70+
}
71+
72+
// Obtener los vectores normales
73+
if (mesh->HasNormals()) {
74+
aiVector3D n = mesh->mNormals[i];
75+
normal.push_back(glm::vec3(n.x, n.y, n.z));
76+
}
77+
}
78+
79+
// Obtener los indices
80+
for (unsigned int i = 0; i < mesh->mNumFaces; i++) {
81+
indices.push_back(mesh->mFaces[i].mIndices[0]);
82+
indices.push_back(mesh->mFaces[i].mIndices[1]);
83+
indices.push_back(mesh->mFaces[i].mIndices[2]);
84+
}
85+
}
86+
87+
void create() {
88+
// generar y activar el VAO
89+
glGenVertexArrays(1, &vao);
90+
glBindVertexArray(vao);
91+
92+
// generar dos ids para los buffer
93+
glGenBuffers(4, buffer);
94+
95+
// buffer de vertices
96+
glBindBuffer(GL_ARRAY_BUFFER, buffer[0]);
97+
glBufferData(GL_ARRAY_BUFFER, vertex.size() * sizeof(glm::vec3), &vertex[0], GL_STATIC_DRAW);
98+
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
99+
glEnableVertexAttribArray(0);
100+
101+
// buffer de textura
102+
if (!uv.empty()) {
103+
glBindBuffer(GL_ARRAY_BUFFER, buffer[1]);
104+
glBufferData(GL_ARRAY_BUFFER, uv.size() * sizeof(glm::vec2), &uv[0], GL_STATIC_DRAW);
105+
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, NULL);
106+
glEnableVertexAttribArray(1);
107+
}
108+
109+
// buffer de normales
110+
if (!normal.empty()) {
111+
glBindBuffer(GL_ARRAY_BUFFER, buffer[2]);
112+
glBufferData(GL_ARRAY_BUFFER, normal.size() * sizeof(glm::vec3), &normal[0], GL_STATIC_DRAW);
113+
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, NULL);
114+
glEnableVertexAttribArray(2);
115+
}
116+
117+
// buffer de indices
118+
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer[3]);
119+
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);
120+
121+
// desactivar el VAO
122+
glBindVertexArray(0);
123+
}
124+
125+
};
126+
127+
class Model {
128+
129+
private:
130+
vector<shared_ptr<Mesh>> meshes;
131+
132+
// procesar recusivamente cada nodo de la escena
133+
void processNode(const aiNode* node, const aiScene* scene)
134+
{
135+
// obtener los mesh de esta escena
136+
for (unsigned int i = 0; i < node->mNumMeshes; i++) {
137+
shared_ptr<Mesh> mesh(new Mesh(scene->mMeshes[node->mMeshes[i]]));
138+
meshes.push_back(mesh);
139+
}
140+
141+
// procesar los hijos del nodo
142+
for (unsigned int i = 0; i < node->mNumChildren; i++)
143+
this->processNode(node->mChildren[i], scene);
144+
}
145+
146+
public:
147+
// cargar el archivo deseado
148+
void init(const std::string& file_name) {
149+
Assimp::Importer importer;
150+
const aiScene* scene = importer.ReadFile(file_name, aiProcess_Triangulate);
151+
152+
if (scene && scene->mRootNode)
153+
processNode(scene->mRootNode, scene);
154+
else cout << importer.GetErrorString() << endl;
155+
}
156+
157+
// dibujar la escena completa
158+
void draw() {
159+
for (auto m : meshes) m->draw();
160+
}
161+
};
162+
163+
class Tutorial_08 : public OpenGLWindow {
164+
165+
public:
166+
Tutorial_08() {
167+
mv_matrix = 0;
168+
view_matrix = 0;
169+
proj_matrix = 0;
170+
}
171+
172+
private:
173+
void onstart() override {
174+
175+
glEnable(GL_DEPTH_TEST);
176+
glClearColor(0.25f, 0.80f, 0.75f, 1.0f);
177+
178+
GLuint program = shader_simple.compile("shaders/phong.vertex_shader", "shaders/phong.fragment_shader");
179+
180+
mv_matrix = glGetUniformLocation(program, "mv_matrix");
181+
view_matrix = glGetUniformLocation(program, "view_matrix");
182+
proj_matrix = glGetUniformLocation(program, "proj_matrix");
183+
184+
model.init("model/cessna.assbin");
185+
}
186+
187+
void onrender(double time) override {
188+
189+
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
190+
191+
// Usar el shader
192+
shader_simple.use();
193+
194+
// Matriz de modelo, se aplica una rotacion sobre el eje Y
195+
glm::mat4 Model;
196+
Model = glm::rotate(Model, (float)time, glm::vec3(0.0f, 1.0f, 0.0f));
197+
Model = glm::scale(Model, glm::vec3(0.5f));
198+
199+
// Matriz de proyeccion y visualizacion
200+
glm::mat4 Projection = glm::perspective(45.0f, aspect_ratio, 0.1f, 100.0f);
201+
glm::mat4 View = glm::lookAt(glm::vec3(0, 5, 20), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));
202+
203+
//Establecer las matrices
204+
glUniformMatrix4fv(mv_matrix, 1, GL_FALSE, glm::value_ptr(View * Model));
205+
glUniformMatrix4fv(view_matrix, 1, GL_FALSE, glm::value_ptr(View));
206+
glUniformMatrix4fv(proj_matrix, 1, GL_FALSE, glm::value_ptr(Projection));
207+
208+
// dibujar el modelo
209+
model.draw();
210+
211+
// desactivar el uso del shader
212+
shader_simple.unUse();
213+
}
214+
215+
void onstop() override {
216+
217+
}
218+
219+
Model model;
220+
OpenGLShader shader_simple;
221+
GLuint mv_matrix, view_matrix, proj_matrix;
222+
};
223+
224+
int main() {
225+
Tutorial_08 win_app;
226+
if (win_app.init("OpenGL Moderno - ASSIMP", 1280, 720)) {
227+
win_app.info();
228+
win_app.run();
229+
}
230+
return 0;
231+
}

‎Tutorial-08/cessna.assbin

229 KB
Binary file not shown.

‎Tutorial-08/phong.fragment_shader

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#version 330 core
2+
3+
out vec4 color;
4+
5+
in vec3 N1;
6+
in vec3 L1;
7+
in vec3 V1;
8+
9+
uniform vec3 light_color = vec3(0.75, 0.75, 0.75);
10+
uniform vec3 ambient_color = vec3(0.1);
11+
12+
uniform float ka = 0.10;
13+
uniform float kd = 0.55;
14+
uniform float ks = 0.80;
15+
uniform float n = 32;
16+
17+
void main()
18+
{
19+
// Normalize the incoming N, L, and V vectors
20+
vec3 N = normalize(N1);
21+
vec3 L = normalize(L1);
22+
vec3 V = normalize(V1);
23+
// Calculate R by reflecting -L around the plane defined by N
24+
vec3 R = reflect(-L, N);
25+
26+
// Calculate ambient, difusse, specular contribution
27+
vec3 ambient = ka * ambient_color;
28+
vec3 diffuse = kd * light_color * max(0.0, dot(N, L));
29+
vec3 specular = ks * light_color * pow(max(0.0, dot(R, V)), n);
30+
31+
// Send the color output to the fragment shader
32+
vec3 f_color = ambient + diffuse + specular;
33+
color = vec4(f_color, 1.0);
34+
}

‎Tutorial-08/phong.vertex_shader

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#version 330 core
2+
3+
layout (location = 0) in vec4 position;
4+
layout (location = 1) in vec2 texture;
5+
layout (location = 2) in vec3 normal;
6+
7+
uniform mat4 mv_matrix;
8+
uniform mat4 view_matrix;
9+
uniform mat4 proj_matrix;
10+
11+
uniform vec3 light_pos = vec3(0.0, 3.0, -3.0);
12+
13+
out vec3 N1;
14+
out vec3 L1;
15+
out vec3 V1;
16+
void main(void)
17+
{
18+
// Calculate view-space coordinate
19+
vec4 P = mv_matrix * position;
20+
21+
// Calculate normal in view-space
22+
N1 = mat3(mv_matrix) * normal;
23+
24+
// Calculate light vector
25+
L1 = light_pos - P.xyz;
26+
27+
// Calculate view vector
28+
V1 = -P.xyz;
29+
30+
// Calculate the clip-space position of each vertex
31+
gl_Position = proj_matrix * P;
32+
}

0 commit comments

Comments
 (0)
Please sign in to comment.