Добавлен снеговик, добавлены кординатные оси, рефактор рендеринга
This commit is contained in:
@@ -11,12 +11,6 @@
|
||||
#include <sstream>
|
||||
|
||||
|
||||
enum ParserState {
|
||||
IDLE,
|
||||
COMMENT,
|
||||
READ_STR
|
||||
};
|
||||
|
||||
struct MeshPoint {
|
||||
glm::vec3 point;
|
||||
glm::vec3 normal;
|
||||
@@ -62,123 +56,70 @@ Mesh *MeshLoader::loadMesh(const std::string &filename) {
|
||||
|
||||
std::ifstream file(filename + ".obj", std::ios::in);
|
||||
|
||||
ParserState state = IDLE;
|
||||
int line = 1;
|
||||
|
||||
char tmp_buff[128];
|
||||
int tmp_buff_index = 0;
|
||||
int line_number = 1;
|
||||
glm::vec3 color(0.5f, 0.0f, 1.0f); // дефолтный цвет
|
||||
while (true) {
|
||||
char in;
|
||||
std::string source;
|
||||
while (std::getline(file, source)) {
|
||||
if (source.find("v ") == 0) {
|
||||
// вершина
|
||||
char* end = nullptr;
|
||||
|
||||
file.read(&in, 1);
|
||||
glm::vec3 tmp_point(0, 0, 0);
|
||||
tmp_point.x = std::strtof(source.c_str() + 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;
|
||||
|
||||
if (file.eof()) {
|
||||
break;
|
||||
}
|
||||
glm::vec3 tmp_point(0, 0, 0);
|
||||
tmp_point.x = std::strtof(source.c_str() + 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(source.c_str() + 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'); // до конца строки
|
||||
|
||||
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' || in == 'u') {
|
||||
state = READ_STR;
|
||||
MeshPoint p{};
|
||||
// сначала точка
|
||||
int tmp = std::atoi(vertex.c_str());
|
||||
if (tmp > 0) {
|
||||
tmp -= 1;
|
||||
p.point = points[tmp];
|
||||
}
|
||||
break;
|
||||
|
||||
case COMMENT:
|
||||
// строка коммента, читаем до конца линии
|
||||
if (in == '\n') {
|
||||
state = IDLE;
|
||||
tmp = std::atoi(normal.c_str());
|
||||
if (tmp > 0) {
|
||||
tmp -= 1;
|
||||
p.normal = normals[tmp];
|
||||
}
|
||||
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);
|
||||
p.color = color;
|
||||
|
||||
if (source.find("v ") == 0) {
|
||||
// вершина
|
||||
char* end = nullptr;
|
||||
mesh_points.push_back(p);
|
||||
}
|
||||
} else if (source.find("usemtl ") == 0) {
|
||||
// материал
|
||||
std::string mtl_name = source.substr(7);
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
p.color = color;
|
||||
|
||||
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 {
|
||||
tmp_buff[tmp_buff_index++] = in;
|
||||
for (const auto& m: materials) {
|
||||
if (m.name == mtl_name) {
|
||||
color = m.color;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
line_number++;
|
||||
}
|
||||
|
||||
// тут имеем готовый массив вершин
|
||||
|
@@ -18,7 +18,7 @@
|
||||
#include "window/Events.h"
|
||||
#include "graphics/Mesh.h"
|
||||
#include "graphics/Shader.h"
|
||||
#include "graphics/MeshLoader.h"
|
||||
#include "render.h"
|
||||
|
||||
|
||||
#define SPEED_FACTOR 2.5f
|
||||
@@ -78,32 +78,6 @@ static void updateCameraPosition(Camera& cam, float delta) {
|
||||
}
|
||||
|
||||
|
||||
static Mesh* world;
|
||||
static Mesh* model_mesh;
|
||||
static Shader* shader;
|
||||
static void drawWorld(Camera& cam) {
|
||||
auto projview = cam.getProjection() * cam.getView();
|
||||
shader->use();
|
||||
|
||||
// shader->uniformMatrix("pr", cam.getProjection() * cam.getView());
|
||||
shader->uniformMatrix("projview", projview);
|
||||
shader->uniformMatrix("model", glm::mat4(1.0f));
|
||||
world->draw();
|
||||
|
||||
auto model_scale = glm::scale(glm::mat4(1.0f), glm::vec3(0.5f, 0.5f, 0.5f));
|
||||
|
||||
static float angle = 0.0f;
|
||||
|
||||
auto model_translate = glm::translate(glm::mat4(1.0f), glm::vec3(0, 0, -3));
|
||||
auto model_rotate = glm::rotate(glm::mat4(1.0f), angle, glm::vec3(0, 1, 0));
|
||||
angle += 0.0002f;
|
||||
|
||||
shader->uniformMatrix("model", model_scale * model_translate * model_rotate);
|
||||
// world->draw();
|
||||
model_mesh->draw();
|
||||
}
|
||||
|
||||
|
||||
void mainloop(Camera& camera) {
|
||||
long frame = 0;
|
||||
float lastTime = Window::getTime();
|
||||
@@ -129,51 +103,22 @@ void mainloop(Camera& camera) {
|
||||
|
||||
updateCameraPosition(camera, delta);
|
||||
|
||||
drawWorld(camera);
|
||||
|
||||
// worldRenderer.draw(world, camera, occlusion);
|
||||
// hud.draw(level, assets);
|
||||
// if (devdata) {
|
||||
// hud.drawDebug(level, assets, fps, occlusion);
|
||||
// }
|
||||
renderScene(camera);
|
||||
|
||||
Window::swapBuffers();
|
||||
Events::pullEvents();
|
||||
}
|
||||
}
|
||||
|
||||
void loadResources() {
|
||||
const float buffer[] = {
|
||||
// треугольник
|
||||
// X Y Z nX nY nZ R G B
|
||||
-1, -1, 0.5, 0, 0, 1, 0, 0, 1,
|
||||
1, -1, 0.5, 0, 0, 1, 0, 0, 1,
|
||||
0, 1, 0.5, 0, 0, 1, 0, 0, 1,
|
||||
|
||||
-1, -1, -0.5, 0, 0, -1, 0, 1, 1,
|
||||
1, -1, -0.5, 0, 0, -1, 0, 1, 1,
|
||||
0, 1, -0.5, 0, 0, -1, 0, 1, 1,
|
||||
};
|
||||
const int mesh_attrs[] {
|
||||
3, 3, 3, 0
|
||||
};
|
||||
world = new Mesh(buffer, 6, mesh_attrs);
|
||||
|
||||
model_mesh = MeshLoader::loadMesh("res/cube");
|
||||
|
||||
shader = Shader::loadShader("res/main.vsh", "res/main.fsh");
|
||||
}
|
||||
|
||||
void unloadResources() {
|
||||
delete world;
|
||||
delete shader;
|
||||
}
|
||||
|
||||
int main() {
|
||||
Window::initialize(800, 600, "Lab2");
|
||||
Events::initialize();
|
||||
|
||||
loadResources();
|
||||
if (loadResources() != 0) {
|
||||
std::cerr << "Failed to load resources" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// glDisable(GL_DEPTH_TEST);
|
||||
// glDisable(GL_CULL_FACE);
|
||||
|
66
lab2/src/render.cpp
Normal file
66
lab2/src/render.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
//
|
||||
// Created by vlad on 23.03.23.
|
||||
//
|
||||
|
||||
#include "render.h"
|
||||
#include "graphics/MeshLoader.h"
|
||||
#include "graphics/Shader.h"
|
||||
|
||||
#include <glm/ext/matrix_transform.hpp>
|
||||
|
||||
static Mesh* mesh_xyz;
|
||||
static Mesh* mesh_snowman;
|
||||
|
||||
static Shader* shader;
|
||||
|
||||
|
||||
static void drawSnowman() {
|
||||
auto model_scale = glm::scale(glm::mat4(1.0f), glm::vec3(0.5f, 0.5f, 0.5f));
|
||||
|
||||
static float angle = 0.0f;
|
||||
|
||||
auto model_translate = glm::translate(glm::mat4(1.0f), glm::vec3(3, 2, 5));
|
||||
auto model_rotate = glm::rotate(glm::mat4(1.0f), angle, glm::vec3(0, 1, 0));
|
||||
angle += 0.0002f;
|
||||
|
||||
shader->uniformMatrix("model", model_scale * model_translate * model_rotate);
|
||||
mesh_snowman->draw();
|
||||
}
|
||||
|
||||
|
||||
void renderScene(Camera& cam) {
|
||||
auto projview = cam.getProjection() * cam.getView();
|
||||
shader->use();
|
||||
|
||||
// shader->uniformMatrix("pr", cam.getProjection() * cam.getView());
|
||||
shader->uniformMatrix("projview", projview);
|
||||
shader->uniformMatrix("model", glm::mat4(1.0f));
|
||||
mesh_xyz->draw();
|
||||
|
||||
drawSnowman();
|
||||
}
|
||||
|
||||
int loadResources() {
|
||||
mesh_xyz = MeshLoader::loadMesh("res/xyz");
|
||||
if (mesh_xyz == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
mesh_snowman = MeshLoader::loadMesh("res/snowman");
|
||||
if (mesh_snowman == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
shader = Shader::loadShader("res/main.vsh", "res/main.fsh");
|
||||
if (shader == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void unloadResources() {
|
||||
delete mesh_xyz;
|
||||
delete mesh_snowman;
|
||||
delete shader;
|
||||
}
|
15
lab2/src/render.h
Normal file
15
lab2/src/render.h
Normal file
@@ -0,0 +1,15 @@
|
||||
//
|
||||
// Created by vlad on 23.03.23.
|
||||
//
|
||||
|
||||
#ifndef GRAPHICS_LABS_RENDER_H
|
||||
#define GRAPHICS_LABS_RENDER_H
|
||||
|
||||
#include "window/Camera.h"
|
||||
|
||||
int loadResources();
|
||||
void unloadResources();
|
||||
|
||||
void renderScene(Camera& cam);
|
||||
|
||||
#endif //GRAPHICS_LABS_RENDER_H
|
Reference in New Issue
Block a user