Compare commits
No commits in common. "master" and "v0.1" have entirely different histories.
|
@ -4,43 +4,12 @@
|
|||
"iosfwd": "cpp",
|
||||
"map": "cpp",
|
||||
"atomic": "cpp",
|
||||
"iostream": "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",
|
||||
"iterator": "cpp",
|
||||
"memory": "cpp",
|
||||
"memory_resource": "cpp",
|
||||
"numeric": "cpp",
|
||||
"random": "cpp",
|
||||
"string": "cpp",
|
||||
"system_error": "cpp",
|
||||
"tuple": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"iostream": "cpp",
|
||||
"istream": "cpp",
|
||||
"limits": "cpp",
|
||||
"ostream": "cpp",
|
||||
"sstream": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"typeinfo": "cpp"
|
||||
"new": "cpp"
|
||||
}
|
||||
}
|
|
@ -6,9 +6,6 @@
|
|||
#include "Model.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
|
||||
{
|
||||
|
|
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(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 "Scene.h"
|
||||
#include "Camera.h"
|
||||
#include "Model.h"
|
||||
#include "Texture.h"
|
||||
|
||||
#define WINDOW_WIDTH 800
|
||||
#define WINDOW_HEIGHT 600
|
||||
|
@ -175,9 +177,6 @@ int main(void)
|
|||
return -1;
|
||||
}
|
||||
|
||||
// Включаем проверку по буферу глубины
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
// Компиляция шейдеров
|
||||
GLuint shaderProgram = LoadShaders("shaders/shader.vert", "shaders/shader.frag");
|
||||
// Активация шейдера
|
||||
|
@ -185,8 +184,43 @@ int main(void)
|
|||
// Установим значения текстур
|
||||
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);
|
||||
|
@ -204,10 +238,10 @@ int main(void)
|
|||
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);
|
||||
|
|
Loading…
Reference in New Issue