Добавлена подгрузка материалов (сейчас только цвет)

This commit is contained in:
vlad 2023-03-23 19:31:48 +03:00
parent e7e4852756
commit 273ae90ea3
3 changed files with 64 additions and 13 deletions

View File

@ -2,6 +2,7 @@
layout (location = 0) in vec3 v_position; layout (location = 0) in vec3 v_position;
layout (location = 1) in vec3 v_normal; layout (location = 1) in vec3 v_normal;
layout (location = 2) in vec3 v_color;
out vec4 a_color; out vec4 a_color;
uniform mat4 projview; uniform mat4 projview;
@ -17,6 +18,6 @@ void main(){
// потом [0.5 ... 1] // потом [0.5 ... 1]
l = (l + 2) / 3; l = (l + 2) / 3;
a_color = vec4(vec3(0.5, 0, 1) * l, 1); a_color = vec4(v_color * l, 1);
} }

View File

@ -20,13 +20,45 @@ enum ParserState {
struct MeshPoint { struct MeshPoint {
glm::vec3 point; glm::vec3 point;
glm::vec3 normal; glm::vec3 normal;
glm::vec3 color;
}; };
struct Material {
std::string name;
glm::vec3 color;
};
static void loadMaterials(std::vector<Material>& materials, const std::string &filename) {
std::ifstream file(filename, std::ios::in);
std::string line;
std::string mtl_name;
while (std::getline(file, line)) {
if (line.find("newmtl ") == 0) {
mtl_name = line.substr(7);
} else if (line.find("Kd ") == 0) {
// цвет
char* end = nullptr;
Material m{};
m.name = mtl_name;
m.color.x = std::strtof(line.c_str() + 3, &end);
m.color.y = std::strtof(end, &end);
m.color.z = std::strtof(end, &end);
materials.push_back(m);
}
}
}
Mesh *MeshLoader::loadMesh(const std::string &filename) { Mesh *MeshLoader::loadMesh(const std::string &filename) {
std::vector<glm::vec3> points; std::vector<glm::vec3> points;
std::vector<glm::vec3> normals; std::vector<glm::vec3> normals;
std::vector<MeshPoint> mesh_points; std::vector<MeshPoint> mesh_points;
std::vector<Material> materials;
loadMaterials(materials, filename + ".mtl");
std::ifstream file(filename + ".obj", std::ios::in); std::ifstream file(filename + ".obj", std::ios::in);
@ -35,6 +67,7 @@ Mesh *MeshLoader::loadMesh(const std::string &filename) {
char tmp_buff[128]; char tmp_buff[128];
int tmp_buff_index = 0; int tmp_buff_index = 0;
glm::vec3 color(0.5f, 0.0f, 1.0f); // дефолтный цвет
while (true) { while (true) {
char in; char in;
@ -63,7 +96,7 @@ Mesh *MeshLoader::loadMesh(const std::string &filename) {
if (in == '#' || in == 'o' || in == 's') { if (in == '#' || in == 'o' || in == 's') {
// коммент если это информация о имени объекта или о сглаживании // коммент если это информация о имени объекта или о сглаживании
state = COMMENT; state = COMMENT;
} else if (in == 'v' || in == 'f') { } else if (in == 'v' || in == 'f' || in == 'u') {
state = READ_STR; state = READ_STR;
} }
break; break;
@ -126,8 +159,20 @@ Mesh *MeshLoader::loadMesh(const std::string &filename) {
p.normal = normals[tmp]; p.normal = normals[tmp];
} }
p.color = color;
mesh_points.push_back(p); mesh_points.push_back(p);
} }
} else if (source.find("usemtl ") == 0) {
// материал
std::string mtl_name = source.substr(7);
for (const auto& m: materials) {
if (m.name == mtl_name) {
color = m.color;
break;
}
}
} }
} else { } else {
tmp_buff[tmp_buff_index++] = in; tmp_buff[tmp_buff_index++] = in;
@ -137,9 +182,9 @@ Mesh *MeshLoader::loadMesh(const std::string &filename) {
} }
// тут имеем готовый массив вершин // тут имеем готовый массив вершин
// размер меша = кол-во вершин * (3 + 3) // размер меша = кол-во вершин * (3 + 3 + 3)
const int vertices = (int)mesh_points.size(); const int vertices = (int)mesh_points.size();
auto* out_mesh = new float[vertices * (3 + 3)]; auto* out_mesh = new float[vertices * (3 + 3 + 3)];
int curr_index = 0; int curr_index = 0;
for (const auto& p : mesh_points) { for (const auto& p : mesh_points) {
@ -152,9 +197,14 @@ Mesh *MeshLoader::loadMesh(const std::string &filename) {
out_mesh[curr_index++] = p.normal.x; out_mesh[curr_index++] = p.normal.x;
out_mesh[curr_index++] = p.normal.y; out_mesh[curr_index++] = p.normal.y;
out_mesh[curr_index++] = p.normal.z; out_mesh[curr_index++] = p.normal.z;
// цвет
out_mesh[curr_index++] = p.color.x;
out_mesh[curr_index++] = p.color.y;
out_mesh[curr_index++] = p.color.z;
} }
const int attrs[] = {3, 3, 0}; const int attrs[] = {3, 3, 3, 0};
Mesh* m = new Mesh(out_mesh, vertices, attrs); Mesh* m = new Mesh(out_mesh, vertices, attrs);
delete[] out_mesh; delete[] out_mesh;

View File

@ -145,17 +145,17 @@ void mainloop(Camera& camera) {
void loadResources() { void loadResources() {
const float buffer[] = { const float buffer[] = {
// треугольник // треугольник
// X Y Z nX nY nZ // X Y Z nX nY nZ R G B
-1, -1, 0.5, 0, 0, 1, -1, -1, 0.5, 0, 0, 1, 0, 0, 1,
1, -1, 0.5, 0, 0, 1, 1, -1, 0.5, 0, 0, 1, 0, 0, 1,
0, 1, 0.5, 0, 0, 1, 0, 1, 0.5, 0, 0, 1, 0, 0, 1,
-1, -1, -0.5, 0, 0, -1, -1, -1, -0.5, 0, 0, -1, 0, 1, 1,
1, -1, -0.5, 0, 0, -1, 1, -1, -0.5, 0, 0, -1, 0, 1, 1,
0, 1, -0.5, 0, 0, -1, 0, 1, -0.5, 0, 0, -1, 0, 1, 1,
}; };
const int mesh_attrs[] { const int mesh_attrs[] {
3, 3, 0 3, 3, 3, 0
}; };
world = new Mesh(buffer, 6, mesh_attrs); world = new Mesh(buffer, 6, mesh_attrs);