-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathMesh.cpp
More file actions
executable file
·128 lines (109 loc) · 4.19 KB
/
Mesh.cpp
File metadata and controls
executable file
·128 lines (109 loc) · 4.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include "Mesh.h"
#include <fstream>
#include <iostream>
#include <sstream>
namespace g3d {
MeshBuilder::MeshBuilder() {}
MeshBuilder::~MeshBuilder() {}
MeshBuilder &MeshBuilder::withVertices(std::vector<Vertex> &vertices) {
this->vertices = vertices;
return *this;
}
MeshBuilder &MeshBuilder::fromFile(const std::string &fileName) {
std::vector<unsigned int> vertexIndices, uvIndices, normalIndices;
std::vector<glm::vec3> vertices;
std::vector<glm::vec2> uvs;
std::vector<glm::vec3> normals;
std::ifstream f(fileName);
if (!f)
ENGINE_LOG_ERROR("Cannot load {" + fileName + "}");
ENGINE_LOG_INFO("Loading model {" + fileName + "}");
std::string line;
while (std::getline(f, line)) {
std::stringstream ss(line);
std::string type;
ss >> type;
if (type == "v") {
glm::vec3 vec;
ss >> vec.x >> vec.y >> vec.z;
vertices.push_back(vec);
} else if (type == "vt") {
glm::vec2 vec;
ss >> vec.x >> vec.y;
uvs.push_back(vec);
} else if (type == "vn") {
glm::vec3 vec;
ss >> vec.x >> vec.y >> vec.z;
normals.push_back(glm::normalize(vec));
} else if (type == "f") {
int vertexIndex, uvIndex, normalIndex;
std::string face;
while (ss >> face) {
while (face.find("//") != std::string::npos)
face.replace(face.find("//"), 2, " -1 ");
std::replace(face.begin(), face.end(), '/', ' ');
std::stringstream ss2(face);
ss2 >> vertexIndex >> uvIndex >> normalIndex;
if (vertexIndex != -1)
vertexIndices.push_back(vertexIndex);
if (uvIndex != -1)
uvIndices.push_back(uvIndex);
if (normalIndex != -1)
normalIndices.push_back(normalIndex);
}
}
}
f.close();
for (unsigned int i = 0; i < vertexIndices.size(); i++) {
Vertex vertex;
vertex.position = (vertices.size() > 0) ? vertices[vertexIndices[i] - 1]
: glm::vec3(0.f, 0.f, 0.f);
vertex.normal = (normals.size() > 0) ? normals[normalIndices[i] - 1]
: glm::vec3(0.f, 0.f, 0.f);
vertex.texCoords = (uvs.size() > 0) ? uvs[uvIndices[i] - 1] : glm::vec2(0.f, 0.f);
this->vertices.push_back(vertex);
}
return *this;
}
Mesh *MeshBuilder::build() {
Mesh *newMesh{new Mesh(vertices)};
newMesh->setupBuffers();
return newMesh;
}
Mesh::Mesh(std::vector<Vertex> &vertices) { this->vertices = vertices; }
Mesh::Mesh() {}
Mesh::~Mesh() {}
void Mesh::setVertices(std::vector<Vertex> &vertices) {
this->vertices = vertices;
}
void Mesh::setupBuffers() {
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex),
&vertices[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
(GLvoid *)0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
(GLvoid *)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex),
(GLvoid *)(6 * sizeof(GLfloat)));
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
(GLvoid *)(8 * sizeof(GLfloat)));
glEnableVertexAttribArray(4);
glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
(GLvoid *)(11 * sizeof(GLfloat)));
glBindVertexArray(0);
}
MeshBuilder Mesh::create() { return MeshBuilder(); }
void Mesh::draw() {
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, vertices.size());
glBindVertexArray(0);
}
};