From 19c4383c4e0f956abd6fc2350fb799cd32f6b6fa Mon Sep 17 00:00:00 2001 From: Yusuf Ismail Date: Sun, 14 May 2023 17:44:21 +0100 Subject: [PATCH] Suzanne --- PengEngine.vcxproj | 1 + PengEngine.vcxproj.filters | 1 + resources/meshes/demo/suzanne.asset | 4 +++ resources/scenes/demo/sandbox.json | 20 +++++++++++ src/components/mesh_renderer.cpp | 7 ++-- src/demo/pong/peng_pong.cpp | 3 -- src/rendering/mesh.cpp | 18 +++++++++- src/rendering/mesh.h | 11 ++++-- src/rendering/mesh_decoder.cpp | 53 +++++++++++++++-------------- 9 files changed, 83 insertions(+), 35 deletions(-) create mode 100644 resources/meshes/demo/suzanne.asset diff --git a/PengEngine.vcxproj b/PengEngine.vcxproj index bd46a6f..582a35d 100644 --- a/PengEngine.vcxproj +++ b/PengEngine.vcxproj @@ -630,6 +630,7 @@ xcopy /y /d /s $(SolutionDir)resources $(OutDir)\resources\ + diff --git a/PengEngine.vcxproj.filters b/PengEngine.vcxproj.filters index 308e654..646faf1 100644 --- a/PengEngine.vcxproj.filters +++ b/PengEngine.vcxproj.filters @@ -755,6 +755,7 @@ + diff --git a/resources/meshes/demo/suzanne.asset b/resources/meshes/demo/suzanne.asset new file mode 100644 index 0000000..68567b6 --- /dev/null +++ b/resources/meshes/demo/suzanne.asset @@ -0,0 +1,4 @@ +{ + "name": "Suzanne", + "mesh": "resources/meshes/demo/suzanne.obj" +} \ No newline at end of file diff --git a/resources/scenes/demo/sandbox.json b/resources/scenes/demo/sandbox.json index ff21c26..78be16b 100644 --- a/resources/scenes/demo/sandbox.json +++ b/resources/scenes/demo/sandbox.json @@ -29,6 +29,26 @@ "components::MeshRenderer" ] }, + { + "type": "Entity", + "name": "Suzanne", + "transform": { + "position": { + "x": -30, + "y": -3, + "z": 3 + }, + "rotation": { + "y": 180 + } + }, + "components": [ + { + "type": "components::MeshRenderer", + "mesh": "resources/meshes/demo/suzanne.asset" + } + ] + }, { "type": "entities::Camera", "transform": { diff --git a/src/components/mesh_renderer.cpp b/src/components/mesh_renderer.cpp index ba525db..13ac1a3 100644 --- a/src/components/mesh_renderer.cpp +++ b/src/components/mesh_renderer.cpp @@ -1,13 +1,16 @@ #include "mesh_renderer.h" +#include +#include +#include #include #include #include #include +#include #include #include #include -#include #include #include @@ -33,7 +36,7 @@ MeshRenderer::MeshRenderer( , _mesh(std::move(mesh)) , _material(std::move(material)) { - // TODO: serialize _mesh + SERIALIZED_MEMBER(_mesh); // TODO: serialize _material } diff --git a/src/demo/pong/peng_pong.cpp b/src/demo/pong/peng_pong.cpp index 78426a5..9ad8993 100644 --- a/src/demo/pong/peng_pong.cpp +++ b/src/demo/pong/peng_pong.cpp @@ -17,7 +17,6 @@ #include "goal.h" #include "paddle.h" #include "pause_menu.h" -#include "rendering/mesh_decoder.h" IMPLEMENT_ENTITY(demo::pong::PengPong); @@ -48,8 +47,6 @@ void PengPong::post_create() build_camera(); build_main_menu(); - MeshDecoder::load_file("resources/meshes/demo/suzanne.obj"); - Logger::success("PengPong started"); } diff --git a/src/rendering/mesh.cpp b/src/rendering/mesh.cpp index 0b7e279..aa9d4dd 100644 --- a/src/rendering/mesh.cpp +++ b/src/rendering/mesh.cpp @@ -2,11 +2,14 @@ #include #include -#include #include +#include #include +#include #include +#include "mesh_decoder.h" + using namespace rendering; using namespace math; @@ -53,6 +56,13 @@ Mesh::Mesh(const std::string& name, const RawMeshData& raw_data) ) { } +Mesh::Mesh(const std::string& name, const std::string& mesh_path) + : Mesh( + name, + MeshDecoder::load_file(mesh_path) + ) +{ } + Mesh::~Mesh() { SCOPED_EVENT("Destroying mesh", _name.c_str()); @@ -63,6 +73,12 @@ Mesh::~Mesh() glDeleteVertexArrays(1, &_vao); } +peng::shared_ref Mesh::load_asset(const Archive& archive) +{ + const std::string mesh_path = archive.read("mesh"); + return memory::GC::alloc(archive.name, mesh_path); +} + void Mesh::render() const { bind(); diff --git a/src/rendering/mesh.h b/src/rendering/mesh.h index dbe3fc7..acd5be0 100644 --- a/src/rendering/mesh.h +++ b/src/rendering/mesh.h @@ -1,12 +1,14 @@ #pragma once #include -#include - #include +#include + #include "raw_mesh_data.h" +struct Archive; + namespace rendering { // TODO: generate bounds for the mesh to be used in culling @@ -15,11 +17,14 @@ namespace rendering public: Mesh(std::string&& name, RawMeshData&& raw_data); Mesh(const std::string& name, const RawMeshData& raw_data); + Mesh(const std::string& name, const std::string& mesh_path); Mesh(const Mesh&) = delete; Mesh(Mesh&&) = delete; ~Mesh(); + static peng::shared_ref load_asset(const Archive& archive); + // Renders the mesh // A shader/material must already be in use before calling this void render() const; @@ -41,4 +46,4 @@ namespace rendering GLuint _vbo; GLuint _vao; }; -} \ No newline at end of file +} diff --git a/src/rendering/mesh_decoder.cpp b/src/rendering/mesh_decoder.cpp index 05b47db..d31964b 100644 --- a/src/rendering/mesh_decoder.cpp +++ b/src/rendering/mesh_decoder.cpp @@ -124,13 +124,13 @@ RawMeshData MeshDecoder::load_obj(const std::string& path) line_number, line.c_str() ); - Vector3u triangle; + uint32_t triangle[3]; for (uint8_t i = 0; i < 3; i++) { - const std::string& token = tokens[1 + i]; + const std::string& vertex_token = tokens[1 + i]; uint32_t vertex_index; - if (const auto it = vertex_cache.find(token); it != vertex_cache.end()) + if (const auto it = vertex_cache.find(vertex_token); it != vertex_cache.end()) { vertex_index = it->second; } @@ -139,52 +139,53 @@ RawMeshData MeshDecoder::load_obj(const std::string& path) // Decode token static thread_local std::vector inner_tokens; inner_tokens.clear(); - strtools::split(token, '/', std::back_inserter(inner_tokens)); + strtools::split(vertex_token, '/', std::back_inserter(inner_tokens)); DECODE_CHECK(inner_tokens.size() == 3, "Invalid OBJ file - vertex '%s' does not use the v/vt/vn format\n%d: %s", - line_number, token.c_str(), line.c_str() + line_number, vertex_token.c_str(), line.c_str() ); + // OBJ files use 1 indexing instead of 0 indexing const uint32_t position_index = std::stoi(inner_tokens[0]); const uint32_t tex_coord_index = std::stoi(inner_tokens[1]); const uint32_t normal_index = std::stoi(inner_tokens[2]); - if (!(position_index < vertex_positions.size())) - { - Logger::error("Invalid OBJ file - vertex '%s' has invalid position index %d\n%d: %s", token.c_str(), position_index, line_number, line.c_str()); return RawMeshData::corrupt_data(); - } do {} while (0); + DECODE_CHECK(position_index <= vertex_positions.size(), + "Invalid OBJ file - vertex '%s' has invalid position index %d\n%d: %s", + vertex_token.c_str(), position_index, line_number, line.c_str() + ); - DECODE_CHECK(tex_coord_index < uv_coords.size(), + DECODE_CHECK(tex_coord_index <= uv_coords.size(), "Invalid OBJ file - vertex '%s' has invalid tex coord index %d\n%d: %s", - token.c_str(), tex_coord_index, line_number, line.c_str() + vertex_token.c_str(), tex_coord_index, line_number, line.c_str() ); - DECODE_CHECK(normal_index < vertex_normals.size(), + DECODE_CHECK(normal_index <= vertex_normals.size(), "Invalid OBJ file - vertex '%s' has invalid normal index %d\n%d: %s", - token.c_str(), normal_index, line_number, line.c_str() + vertex_token.c_str(), normal_index, line_number, line.c_str() ); const Vertex vertex( - vertex_positions[position_index], - vertex_normals[normal_index], - uv_coords[tex_coord_index] + vertex_positions[position_index - 1], + vertex_normals[normal_index - 1], + uv_coords[tex_coord_index - 1] ); - vertex_index = vertex_cache[token] = static_cast(raw_data.vertices.size()); - raw_data.vertices.push_back(vertex); - } + vertex_index = static_cast(raw_data.vertices.size()); + vertex_cache[vertex_token] = vertex_index; - switch (i) - { - case 0: triangle.x = vertex_index; break; - case 1: triangle.y = vertex_index; break; - case 2: triangle.z = vertex_index; break; - default: break; + raw_data.vertices.push_back(vertex); } - raw_data.triangles.push_back(triangle); + triangle[i] = vertex_index; } + + raw_data.triangles.emplace_back( + triangle[0], + triangle[1], + triangle[2] + ); } }