Добавление MeshLoader, он умеет загружать геометрию и нормали из .obj файлов
This commit is contained in:
parent
1b623c947a
commit
bd12a62be1
@ -22,7 +22,7 @@ add_executable(
|
|||||||
src/graphics/Mesh.cpp
|
src/graphics/Mesh.cpp
|
||||||
src/graphics/Shader.h
|
src/graphics/Shader.h
|
||||||
src/graphics/Shader.cpp
|
src/graphics/Shader.cpp
|
||||||
)
|
src/graphics/MeshLoader.cpp src/graphics/MeshLoader.h)
|
||||||
|
|
||||||
target_link_libraries(${PROJECT_NAME} glfw)
|
target_link_libraries(${PROJECT_NAME} glfw)
|
||||||
target_link_libraries(${PROJECT_NAME} GLEW::GLEW)
|
target_link_libraries(${PROJECT_NAME} GLEW::GLEW)
|
||||||
|
BIN
lab2/res/cube.blend
Normal file
BIN
lab2/res/cube.blend
Normal file
Binary file not shown.
12
lab2/res/cube.mtl
Normal file
12
lab2/res/cube.mtl
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# Blender MTL File: 'cube.blend'
|
||||||
|
# Material Count: 1
|
||||||
|
|
||||||
|
newmtl Material
|
||||||
|
Ns 250.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Kd 0.800000 0.800000 0.800000
|
||||||
|
Ks 0.500000 0.500000 0.500000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.000000
|
||||||
|
d 1.000000
|
||||||
|
illum 2
|
32
lab2/res/cube.obj
Normal file
32
lab2/res/cube.obj
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
# Blender v3.4.1 OBJ File: 'cube.blend'
|
||||||
|
# www.blender.org
|
||||||
|
mtllib cube.mtl
|
||||||
|
o Cube
|
||||||
|
v 1.000000 1.000000 -1.000000
|
||||||
|
v 1.000000 -1.000000 -1.000000
|
||||||
|
v 1.000000 1.000000 1.000000
|
||||||
|
v 1.000000 -1.000000 1.000000
|
||||||
|
v -1.000000 1.000000 -1.000000
|
||||||
|
v -1.000000 -1.000000 -1.000000
|
||||||
|
v -1.000000 1.000000 1.000000
|
||||||
|
v -1.000000 -1.000000 1.000000
|
||||||
|
vn 0.0000 1.0000 0.0000
|
||||||
|
vn 0.0000 0.0000 1.0000
|
||||||
|
vn -1.0000 0.0000 0.0000
|
||||||
|
vn 0.0000 -1.0000 0.0000
|
||||||
|
vn 1.0000 0.0000 0.0000
|
||||||
|
vn 0.0000 0.0000 -1.0000
|
||||||
|
usemtl Material
|
||||||
|
s off
|
||||||
|
f 5//1 3//1 1//1
|
||||||
|
f 3//2 8//2 4//2
|
||||||
|
f 7//3 6//3 8//3
|
||||||
|
f 2//4 8//4 6//4
|
||||||
|
f 1//5 4//5 2//5
|
||||||
|
f 5//6 2//6 6//6
|
||||||
|
f 5//1 7//1 3//1
|
||||||
|
f 3//2 7//2 8//2
|
||||||
|
f 7//3 5//3 6//3
|
||||||
|
f 2//4 4//4 8//4
|
||||||
|
f 1//5 3//5 4//5
|
||||||
|
f 5//6 1//6 2//6
|
@ -1,7 +1,7 @@
|
|||||||
#version 330 core
|
#version 330 core
|
||||||
|
|
||||||
layout (location = 0) in vec3 v_position;
|
layout (location = 0) in vec3 v_position;
|
||||||
layout (location = 1) in float light;
|
layout (location = 1) in vec3 v_normal;
|
||||||
|
|
||||||
out vec4 a_color;
|
out vec4 a_color;
|
||||||
uniform mat4 projview;
|
uniform mat4 projview;
|
||||||
@ -9,6 +9,6 @@ uniform mat4 projview;
|
|||||||
void main(){
|
void main(){
|
||||||
// gl_Position = vec4(v_position, 1) * projview;
|
// gl_Position = vec4(v_position, 1) * projview;
|
||||||
gl_Position = projview * vec4(v_position, 1);
|
gl_Position = projview * vec4(v_position, 1);
|
||||||
a_color = vec4(0.5, 0, 1, 1) * light;
|
a_color = vec4(0.5, 0, 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ void Mesh::reload(const float* buffer, size_t vertices){
|
|||||||
this->vertices = vertices;
|
this->vertices = vertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mesh::draw(){
|
void Mesh::draw() const{
|
||||||
glBindVertexArray(vao);
|
glBindVertexArray(vao);
|
||||||
glDrawArrays(GL_TRIANGLES, 0, vertices);
|
glDrawArrays(GL_TRIANGLES, 0, vertices);
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
|
@ -13,7 +13,7 @@ public:
|
|||||||
~Mesh();
|
~Mesh();
|
||||||
|
|
||||||
void reload(const float* buffer, size_t vertices);
|
void reload(const float* buffer, size_t vertices);
|
||||||
void draw();
|
void draw() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* GRAPHICS_MESH_H_ */
|
#endif /* GRAPHICS_MESH_H_ */
|
||||||
|
162
lab2/src/graphics/MeshLoader.cpp
Normal file
162
lab2/src/graphics/MeshLoader.cpp
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
//
|
||||||
|
// Created by vlad on 23.03.23.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "MeshLoader.h"
|
||||||
|
#include <vector>
|
||||||
|
#include <glm/vec3.hpp>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <glm/vec2.hpp>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
|
||||||
|
enum ParserState {
|
||||||
|
IDLE,
|
||||||
|
COMMENT,
|
||||||
|
READ_STR
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MeshPoint {
|
||||||
|
glm::vec3 point;
|
||||||
|
glm::vec3 normal;
|
||||||
|
};
|
||||||
|
|
||||||
|
Mesh *MeshLoader::loadMesh(const std::string &filename) {
|
||||||
|
std::vector<glm::vec3> points;
|
||||||
|
std::vector<glm::vec3> normals;
|
||||||
|
std::vector<MeshPoint> mesh_points;
|
||||||
|
|
||||||
|
|
||||||
|
std::ifstream file(filename + ".obj", std::ios::in);
|
||||||
|
|
||||||
|
ParserState state = IDLE;
|
||||||
|
int line = 1;
|
||||||
|
|
||||||
|
char tmp_buff[128];
|
||||||
|
int tmp_buff_index = 0;
|
||||||
|
while (true) {
|
||||||
|
char in;
|
||||||
|
|
||||||
|
file.read(&in, 1);
|
||||||
|
|
||||||
|
if (file.eof()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tmp_buff_index >= 128) {
|
||||||
|
std::cerr << "[MeshLoader] Error: tmp buffer overflow"
|
||||||
|
" (line " << line << " file: " << filename << ")" << std::endl;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in == '\n') {
|
||||||
|
line++;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case IDLE:
|
||||||
|
tmp_buff[0] = in;
|
||||||
|
tmp_buff_index = 1;
|
||||||
|
|
||||||
|
// нет состояния, возможно после пустой строки
|
||||||
|
if (in == '#' || in == 'o' || in == 's') {
|
||||||
|
// коммент если это информация о имени объекта или о сглаживании
|
||||||
|
state = COMMENT;
|
||||||
|
} else if (in == 'v' || in == 'f') {
|
||||||
|
state = READ_STR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case COMMENT:
|
||||||
|
// строка коммента, читаем до конца линии
|
||||||
|
if (in == '\n') {
|
||||||
|
state = IDLE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case READ_STR:
|
||||||
|
if (in == '\n') {
|
||||||
|
state = IDLE;
|
||||||
|
// парсим строку
|
||||||
|
tmp_buff[tmp_buff_index] = 0; // делаем null-terminator
|
||||||
|
tmp_buff_index = 0;
|
||||||
|
std::string source(tmp_buff);
|
||||||
|
|
||||||
|
if (source.find("v ") == 0) {
|
||||||
|
// вершина
|
||||||
|
char* end = nullptr;
|
||||||
|
|
||||||
|
glm::vec3 tmp_point(0, 0, 0);
|
||||||
|
tmp_point.x = std::strtof(tmp_buff + 2, &end);
|
||||||
|
tmp_point.y = std::strtof(end, &end);
|
||||||
|
tmp_point.z = std::strtof(end, &end);
|
||||||
|
points.push_back(tmp_point);
|
||||||
|
} else if (source.find("vn ") == 0) {
|
||||||
|
// нормаль
|
||||||
|
char* end = nullptr;
|
||||||
|
|
||||||
|
glm::vec3 tmp_point(0, 0, 0);
|
||||||
|
tmp_point.x = std::strtof(tmp_buff + 3, &end);
|
||||||
|
tmp_point.y = std::strtof(end, &end);
|
||||||
|
tmp_point.z = std::strtof(end, &end);
|
||||||
|
normals.push_back(tmp_point);
|
||||||
|
} else if (source.find("f ") == 0) {
|
||||||
|
// фрагмент, он же треугольник
|
||||||
|
std::istringstream source_stream(tmp_buff + 2);
|
||||||
|
std::string point;
|
||||||
|
while (getline(source_stream, point, ' ')) {
|
||||||
|
std::istringstream point_stream(point);
|
||||||
|
std::string vertex, texture, normal;
|
||||||
|
getline(point_stream, vertex, '/');
|
||||||
|
getline(point_stream, texture, '/');
|
||||||
|
getline(point_stream, normal, '\0'); // до конца строки
|
||||||
|
|
||||||
|
MeshPoint p{};
|
||||||
|
// сначала точка
|
||||||
|
int tmp = std::atoi(vertex.c_str());
|
||||||
|
if (tmp > 0) {
|
||||||
|
tmp -= 1;
|
||||||
|
p.point = points[tmp];
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = std::atoi(normal.c_str());
|
||||||
|
if (tmp > 0) {
|
||||||
|
tmp -= 1;
|
||||||
|
p.normal = normals[tmp];
|
||||||
|
}
|
||||||
|
|
||||||
|
mesh_points.push_back(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tmp_buff[tmp_buff_index++] = in;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// тут имеем готовый массив вершин
|
||||||
|
// размер меша = кол-во вершин * (3 + 3)
|
||||||
|
const int vertices = (int)mesh_points.size();
|
||||||
|
auto* out_mesh = new float[vertices * (3 + 3)];
|
||||||
|
|
||||||
|
int curr_index = 0;
|
||||||
|
for (const auto& p : mesh_points) {
|
||||||
|
// точка
|
||||||
|
out_mesh[curr_index++] = p.point.x;
|
||||||
|
out_mesh[curr_index++] = p.point.y;
|
||||||
|
out_mesh[curr_index++] = p.point.z;
|
||||||
|
|
||||||
|
// нормаль
|
||||||
|
out_mesh[curr_index++] = p.normal.x;
|
||||||
|
out_mesh[curr_index++] = p.normal.y;
|
||||||
|
out_mesh[curr_index++] = p.normal.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int attrs[] = {3, 3, 0};
|
||||||
|
Mesh* m = new Mesh(out_mesh, vertices, attrs);
|
||||||
|
|
||||||
|
delete[] out_mesh;
|
||||||
|
return m;
|
||||||
|
}
|
18
lab2/src/graphics/MeshLoader.h
Normal file
18
lab2/src/graphics/MeshLoader.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
//
|
||||||
|
// Created by vlad on 23.03.23.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef GRAPHICS_LABS_MESHLOADER_H
|
||||||
|
#define GRAPHICS_LABS_MESHLOADER_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include "Mesh.h"
|
||||||
|
|
||||||
|
class MeshLoader {
|
||||||
|
public:
|
||||||
|
static Mesh *loadMesh(const std::string &filename);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //GRAPHICS_LABS_MESHLOADER_H
|
@ -18,6 +18,7 @@
|
|||||||
#include "window/Events.h"
|
#include "window/Events.h"
|
||||||
#include "graphics/Mesh.h"
|
#include "graphics/Mesh.h"
|
||||||
#include "graphics/Shader.h"
|
#include "graphics/Shader.h"
|
||||||
|
#include "graphics/MeshLoader.h"
|
||||||
|
|
||||||
|
|
||||||
#define SPEED_FACTOR 2.5f
|
#define SPEED_FACTOR 2.5f
|
||||||
@ -78,6 +79,7 @@ static void updateCameraPosition(Camera& cam, float delta) {
|
|||||||
|
|
||||||
|
|
||||||
static Mesh* world;
|
static Mesh* world;
|
||||||
|
static Mesh* model_mesh;
|
||||||
static Shader* shader;
|
static Shader* shader;
|
||||||
static void drawWorld(Camera& cam) {
|
static void drawWorld(Camera& cam) {
|
||||||
auto projview = cam.getProjection() * cam.getView();
|
auto projview = cam.getProjection() * cam.getView();
|
||||||
@ -96,7 +98,8 @@ static void drawWorld(Camera& cam) {
|
|||||||
angle += 0.001f;
|
angle += 0.001f;
|
||||||
|
|
||||||
shader->uniformMatrix("projview", projview * model_scale * model_translate * model_rotate);
|
shader->uniformMatrix("projview", projview * model_scale * model_translate * model_rotate);
|
||||||
world->draw();
|
// world->draw();
|
||||||
|
model_mesh->draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -141,20 +144,22 @@ void mainloop(Camera& camera) {
|
|||||||
void loadResources() {
|
void loadResources() {
|
||||||
const float buffer[] = {
|
const float buffer[] = {
|
||||||
// треугольник
|
// треугольник
|
||||||
// X Y Z Light
|
// X Y Z nX nY nZ
|
||||||
-1, -1, 0.5, 0.5,
|
-1, -1, 0.5, 0, 0, 1,
|
||||||
1, -1, 0.5, 0.1,
|
1, -1, 0.5, 0, 0, 1,
|
||||||
0, 1, 0.5, 0.9,
|
0, 1, 0.5, 0, 0, 1,
|
||||||
|
|
||||||
-1, -1, -0.5, 0.5,
|
-1, -1, -0.5, 0, 0, -1,
|
||||||
1, -1, -0.5, 0.1,
|
1, -1, -0.5, 0, 0, -1,
|
||||||
0, 1, -0.5, 0.9,
|
0, 1, -0.5, 0, 0, -1,
|
||||||
};
|
};
|
||||||
const int mesh_attrs[] {
|
const int mesh_attrs[] {
|
||||||
3, 1, 0
|
3, 3, 0
|
||||||
};
|
};
|
||||||
world = new Mesh(buffer, 6, mesh_attrs);
|
world = new Mesh(buffer, 6, mesh_attrs);
|
||||||
|
|
||||||
|
model_mesh = MeshLoader::loadMesh("res/cube");
|
||||||
|
|
||||||
shader = Shader::loadShader("res/main.vsh", "res/main.fsh");
|
shader = Shader::loadShader("res/main.vsh", "res/main.fsh");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user