Compare commits
No commits in common. "master" and "v0.1" have entirely different histories.
|
@ -4,43 +4,12 @@
|
||||||
"iosfwd": "cpp",
|
"iosfwd": "cpp",
|
||||||
"map": "cpp",
|
"map": "cpp",
|
||||||
"atomic": "cpp",
|
"atomic": "cpp",
|
||||||
|
"iostream": "cpp",
|
||||||
"array": "cpp",
|
"array": "cpp",
|
||||||
"*.tcc": "cpp",
|
|
||||||
"cctype": "cpp",
|
|
||||||
"clocale": "cpp",
|
|
||||||
"cmath": "cpp",
|
|
||||||
"cstdarg": "cpp",
|
|
||||||
"cstddef": "cpp",
|
|
||||||
"cstdint": "cpp",
|
|
||||||
"cstdio": "cpp",
|
|
||||||
"cstdlib": "cpp",
|
|
||||||
"cstring": "cpp",
|
|
||||||
"cwchar": "cpp",
|
|
||||||
"cwctype": "cpp",
|
|
||||||
"deque": "cpp",
|
|
||||||
"unordered_map": "cpp",
|
|
||||||
"vector": "cpp",
|
|
||||||
"exception": "cpp",
|
|
||||||
"algorithm": "cpp",
|
|
||||||
"functional": "cpp",
|
"functional": "cpp",
|
||||||
"iterator": "cpp",
|
|
||||||
"memory": "cpp",
|
|
||||||
"memory_resource": "cpp",
|
|
||||||
"numeric": "cpp",
|
|
||||||
"random": "cpp",
|
|
||||||
"string": "cpp",
|
|
||||||
"system_error": "cpp",
|
|
||||||
"tuple": "cpp",
|
"tuple": "cpp",
|
||||||
"type_traits": "cpp",
|
"type_traits": "cpp",
|
||||||
"utility": "cpp",
|
"utility": "cpp",
|
||||||
"initializer_list": "cpp",
|
"new": "cpp"
|
||||||
"iostream": "cpp",
|
}
|
||||||
"istream": "cpp",
|
|
||||||
"limits": "cpp",
|
|
||||||
"ostream": "cpp",
|
|
||||||
"sstream": "cpp",
|
|
||||||
"stdexcept": "cpp",
|
|
||||||
"streambuf": "cpp",
|
|
||||||
"cinttypes": "cpp",
|
|
||||||
"typeinfo": "cpp"
|
|
||||||
}
|
}
|
|
@ -6,9 +6,6 @@
|
||||||
#include "Model.h"
|
#include "Model.h"
|
||||||
#include "Camera.h"
|
#include "Camera.h"
|
||||||
|
|
||||||
#define DEFAULT_MTL_DIR "./"
|
|
||||||
class Scene loadOBJtoScene(const char* filename, const char* mtl_directory = DEFAULT_MTL_DIR, const char* texture_directory = DEFAULT_MTL_DIR);
|
|
||||||
|
|
||||||
// Класс сцены
|
// Класс сцены
|
||||||
class Scene
|
class Scene
|
||||||
{
|
{
|
||||||
|
|
124
src/Scene.cpp
124
src/Scene.cpp
|
@ -87,127 +87,3 @@ void Scene::rebuld_tree(const Scene& from)
|
||||||
rebuild_Nodes_list(models, from);
|
rebuild_Nodes_list(models, from);
|
||||||
rebuild_Nodes_list(cameras, from);
|
rebuild_Nodes_list(cameras, from);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TINYOBJLOADER_IMPLEMENTATION
|
|
||||||
#include "tiny_obj_loader.h"
|
|
||||||
|
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
inline void hash_combine(std::size_t& seed) { }
|
|
||||||
|
|
||||||
template <typename T, typename... Rest>
|
|
||||||
inline void hash_combine(std::size_t& seed, const T& v, Rest... rest) {
|
|
||||||
std::hash<T> hasher;
|
|
||||||
seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
|
|
||||||
hash_combine(seed, rest...);
|
|
||||||
}
|
|
||||||
|
|
||||||
Scene loadOBJtoScene(const char* filename, const char* mtl_directory, const char* texture_directory)
|
|
||||||
{
|
|
||||||
Scene result;
|
|
||||||
Model model;
|
|
||||||
// Все модели образованные на основании этой модели будут иметь общего родителя
|
|
||||||
model.setParent(&result.root);
|
|
||||||
|
|
||||||
tinyobj::attrib_t attrib;
|
|
||||||
std::vector<tinyobj::shape_t> shapes;
|
|
||||||
std::vector<tinyobj::material_t> materials;
|
|
||||||
|
|
||||||
std::string err;
|
|
||||||
|
|
||||||
// Если в процессе загрузки возникли ошибки - выдадим исключение
|
|
||||||
if (!tinyobj::LoadObj(&attrib, &shapes, &materials, &err, filename, mtl_directory))
|
|
||||||
throw std::runtime_error(err);
|
|
||||||
|
|
||||||
std::vector<GLuint> indices; // индексы модели
|
|
||||||
std::vector<glm::vec3> verteces; // вершины
|
|
||||||
std::vector<glm::vec3> normals; // нормали
|
|
||||||
std::vector<glm::vec2> texCords; // текстурные координаты
|
|
||||||
size_t hash; // Для уникальных вершин
|
|
||||||
std::map <int, int> uniqueVerteces; // словарь для уникальных вершин: ключ - хеш, значение - индекс вершины
|
|
||||||
|
|
||||||
int last_material_index = 0; // индекс последнего материала (для группировки моделей)
|
|
||||||
int count = 0, offset; // для индексов начала и конца в индексном буфере
|
|
||||||
std::vector<int> materials_range; // хранилище индексов
|
|
||||||
std::vector<int> materials_ids; // индексы материалов
|
|
||||||
|
|
||||||
materials_range.push_back(count); // Закидываем начало отрезка в индексном буфере
|
|
||||||
// Цикл по считанным моделям
|
|
||||||
for (const auto& shape : shapes)
|
|
||||||
{
|
|
||||||
offset = count; // Переменная для
|
|
||||||
last_material_index = shape.mesh.material_ids[(count - offset)/3]; // Запоминаем индекс материала
|
|
||||||
|
|
||||||
// Цикл по индексам модели
|
|
||||||
for (const auto& index : shape.mesh.indices)
|
|
||||||
{
|
|
||||||
hash = 0;
|
|
||||||
hash_combine( hash
|
|
||||||
, attrib.vertices[3 * index.vertex_index + 0], attrib.vertices[3 * index.vertex_index + 1], attrib.vertices[3 * index.vertex_index + 2]
|
|
||||||
, attrib.normals[3 * index.normal_index + 0], attrib.normals[3 * index.normal_index + 1], attrib.normals[3 * index.normal_index + 2]
|
|
||||||
, attrib.texcoords[2 * index.texcoord_index + 0], attrib.texcoords[2 * index.texcoord_index + 1]);
|
|
||||||
|
|
||||||
if (!uniqueVerteces.count(hash))
|
|
||||||
{
|
|
||||||
uniqueVerteces[hash] = verteces.size();
|
|
||||||
|
|
||||||
// группируем вершины в массив на основании индексов
|
|
||||||
verteces.push_back({ attrib.vertices[3 * index.vertex_index + 0]
|
|
||||||
, attrib.vertices[3 * index.vertex_index + 1]
|
|
||||||
, attrib.vertices[3 * index.vertex_index + 2]
|
|
||||||
});
|
|
||||||
// группируем нормали в массив на основании индексов
|
|
||||||
normals.push_back({ attrib.normals[3 * index.normal_index + 0]
|
|
||||||
, attrib.normals[3 * index.normal_index + 1]
|
|
||||||
, attrib.normals[3 * index.normal_index + 2]
|
|
||||||
});
|
|
||||||
// группируем текстурные координаты в массив на основании индексов
|
|
||||||
texCords.push_back({ attrib.texcoords[2 * index.texcoord_index + 0]
|
|
||||||
, 1-attrib.texcoords[2 * index.texcoord_index + 1]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// Сохраняем индекс в массив
|
|
||||||
indices.push_back(uniqueVerteces[hash]);
|
|
||||||
|
|
||||||
// Если индекс последнего материала изменился, то необходимо сохранить его
|
|
||||||
if (last_material_index != shape.mesh.material_ids[(count - offset)/3])
|
|
||||||
{
|
|
||||||
materials_range.push_back(count); // как конец отрезка
|
|
||||||
materials_ids.push_back(last_material_index); // как используемый материал
|
|
||||||
last_material_index = shape.mesh.material_ids[(count - offset)/3];
|
|
||||||
}
|
|
||||||
count++;
|
|
||||||
} // for (const auto& index : shape.mesh.indices)
|
|
||||||
|
|
||||||
// Если последний материал не загружен - загружаем его
|
|
||||||
if (materials_range[materials_range.size()-1] != count-1)
|
|
||||||
{
|
|
||||||
materials_range.push_back(count); // последний конец отрезка
|
|
||||||
materials_ids.push_back(last_material_index); // последний используемый материал
|
|
||||||
}
|
|
||||||
} // for (const auto& shape : shapes)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Загрузка в буферы
|
|
||||||
model.load_verteces (&verteces[0], verteces.size());
|
|
||||||
model.load_normals (&normals[0], normals.size());
|
|
||||||
model.load_texCoords(&texCords[0], texCords.size());
|
|
||||||
// Загрузка индексного буфера
|
|
||||||
model.load_indices (&indices[0], indices.size());
|
|
||||||
|
|
||||||
|
|
||||||
// Создаем копии модели, которые будут рендериться в заданном диапазоне
|
|
||||||
// И присваиваем текстуры копиям на основании материала
|
|
||||||
for (int i = 0; i < materials_range.size()-1; i++)
|
|
||||||
{
|
|
||||||
result.models.push_back(model); // Создание копии с общим VAO
|
|
||||||
auto s = --result.models.end();
|
|
||||||
s->set_index_range(materials_range[i]*sizeof(GLuint), materials_range[i+1]-materials_range[i]);
|
|
||||||
|
|
||||||
Texture diffuse(TEX_DIFFUSE, texture_directory + materials[materials_ids[i]].diffuse_texname);
|
|
||||||
s->set_texture(diffuse);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
50
src/main.cpp
50
src/main.cpp
|
@ -5,7 +5,9 @@
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "Scene.h"
|
#include "Camera.h"
|
||||||
|
#include "Model.h"
|
||||||
|
#include "Texture.h"
|
||||||
|
|
||||||
#define WINDOW_WIDTH 800
|
#define WINDOW_WIDTH 800
|
||||||
#define WINDOW_HEIGHT 600
|
#define WINDOW_HEIGHT 600
|
||||||
|
@ -175,9 +177,6 @@ int main(void)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Включаем проверку по буферу глубины
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
|
||||||
|
|
||||||
// Компиляция шейдеров
|
// Компиляция шейдеров
|
||||||
GLuint shaderProgram = LoadShaders("shaders/shader.vert", "shaders/shader.frag");
|
GLuint shaderProgram = LoadShaders("shaders/shader.vert", "shaders/shader.frag");
|
||||||
// Активация шейдера
|
// Активация шейдера
|
||||||
|
@ -185,8 +184,43 @@ int main(void)
|
||||||
// Установим значения текстур
|
// Установим значения текстур
|
||||||
Texture::init_textures(shaderProgram);
|
Texture::init_textures(shaderProgram);
|
||||||
|
|
||||||
// Загрузка сцены из obj файла
|
// Вершины прямоугольника
|
||||||
Scene scene = loadOBJtoScene("../resources/models/cubes.obj", "../resources/models/", "../resources/textures/");
|
glm::vec3 verticies[] = { {-0.5f, -0.5f, 0.0f}
|
||||||
|
, { 0.5f, -0.5f, 0.0f}
|
||||||
|
, { 0.5f, 0.5f, 0.0f}
|
||||||
|
, {-0.5f, 0.5f, 0.0f}
|
||||||
|
};
|
||||||
|
// Модель прямоугольника
|
||||||
|
Model rectangle;
|
||||||
|
|
||||||
|
// Загрузка вершин модели
|
||||||
|
rectangle.load_verteces(verticies, sizeof(verticies)/sizeof(glm::vec3));
|
||||||
|
|
||||||
|
// индексы вершин
|
||||||
|
GLuint indices[] = {0, 1, 2, 2, 3, 0};
|
||||||
|
|
||||||
|
// Загрузка индексов модели
|
||||||
|
rectangle.load_indices(indices, sizeof(indices));
|
||||||
|
|
||||||
|
// Текстурные координаты
|
||||||
|
glm::vec2 texCoords[] = { {0.0f, 0.0f}
|
||||||
|
, {1.0f, 0.0f}
|
||||||
|
, {1.0f, 1.0f}
|
||||||
|
, {0.0f, 1.0f}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Загрузка текстурных координат модели
|
||||||
|
rectangle.load_texCoords(texCoords, sizeof(texCoords)/sizeof(glm::vec2));
|
||||||
|
|
||||||
|
// Зададим горизонтальное положение перед камерой
|
||||||
|
rectangle.e_position().y = -1;
|
||||||
|
rectangle.e_position().z = 3;
|
||||||
|
rectangle.e_rotation() = {0.707f, 0.707f, 0.0f, 0.0f};
|
||||||
|
rectangle.e_scale() = glm::vec3(3);
|
||||||
|
|
||||||
|
// Текстура травы
|
||||||
|
Texture grass(TEX_DIFFUSE, "../resources/textures/grass.png");
|
||||||
|
rectangle.set_texture(grass);
|
||||||
|
|
||||||
// Установка цвета очистки буфера цвета
|
// Установка цвета очистки буфера цвета
|
||||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
@ -204,10 +238,10 @@ int main(void)
|
||||||
glUniformMatrix4fv(vp_uniform, 1, GL_FALSE, &Camera::current().getVP()[0][0]);
|
glUniformMatrix4fv(vp_uniform, 1, GL_FALSE, &Camera::current().getVP()[0][0]);
|
||||||
|
|
||||||
// Очистка буфера цвета
|
// Очистка буфера цвета
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
// Тут производится рендер
|
// Тут производится рендер
|
||||||
scene.render(model_uniform);
|
rectangle.render(model_uniform);
|
||||||
|
|
||||||
// Представление содержимого буфера цепочки показа на окно
|
// Представление содержимого буфера цепочки показа на окно
|
||||||
glfwSwapBuffers(window);
|
glfwSwapBuffers(window);
|
||||||
|
|
Loading…
Reference in New Issue