diff --git a/assets/shaders/color3d.glsl b/assets/shaders/color3d.glsl index 8bdf313..f02fcad 100644 --- a/assets/shaders/color3d.glsl +++ b/assets/shaders/color3d.glsl @@ -2,10 +2,8 @@ #version 450 core layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec4 a_Color; -layout(location = 2) in vec3 a_Normal; -layout(location = 3) in vec2 a_TexCoord; -layout(location = 4) in int a_EntityID; +layout(location = 1) in vec3 a_Normal; +layout(location = 2) in vec2 a_TexCoord; layout(std140, binding = 0) uniform Camera { @@ -20,25 +18,20 @@ layout(std140, binding = 1) uniform Transform struct VertexOutput { - vec4 Color; vec2 TexCoord; vec3 Normal; vec3 ViewPos; }; layout (location = 0) out VertexOutput Output; -layout (location = 4) out flat int v_EntityID; layout (location = 5) out vec4 v_Pos; void main() { - Output.Color = a_Color; Output.TexCoord = a_TexCoord; Output.Normal = mat3(transpose(inverse(u_Transform))) * a_Normal; Output.ViewPos = u_ViewPosition; - v_EntityID = a_EntityID; - v_Pos = u_Transform * vec4(a_Position, 1.0); gl_Position = u_ViewProjection * v_Pos; } @@ -49,9 +42,22 @@ void main() layout (location = 0) out vec4 color; layout (location = 1) out int color2; +layout (std140, binding = 2) uniform Material +{ + vec4 u_Albedo; + float u_Roughness; + float u_Metallic; + float u_AmbientStrength; + float u_SpecularStrength; +}; + +layout(std140, binding = 3) uniform EditorID +{ + int u_EntityID; +}; + struct VertexOutput { - vec4 Color; vec2 TexCoord; vec3 Normal; vec3 ViewPos; @@ -67,8 +73,7 @@ void main() vec3 lightColor = vec3(1.0f, 1.0f, 1.0f); // Ambiant lighting - float ambientStrength = 0.8; - vec3 ambient = ambientStrength * lightColor; + vec3 ambient = lightColor * u_AmbientStrength; // Diffuse lighting vec3 norm = normalize(Input.Normal); @@ -78,16 +83,19 @@ void main() vec3 diffuse = diff * lightColor; // Specular highlight - float specularStrength = 0.5; vec3 viewDir = normalize(Input.ViewPos - v_Pos.xyz); // .xyz here too vec3 reflectDir = reflect(-lightDir, norm); - float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32); - vec3 specular = specularStrength * spec * lightColor; + float shininess = mix(2.0, 256.0, 1.0 - u_Roughness); + float spec = pow(max(dot(viewDir, reflectDir), 0.0), shininess); + vec3 specularColor = mix(vec3(1.0), u_Albedo.rgb, u_Metallic); + vec3 specular = u_SpecularStrength * spec * lightColor * specularColor; - vec3 result = (ambient + diffuse + specular) * Input.Color.rgb; // objectColor → Input.Color.rgb + // Total + //vec3 result = (ambient + diffuse + specular) * Input.Color.rgb; // objectColor → Input.Color.rgb + vec3 result = (ambient + diffuse + specular) * u_Albedo.rgb; // objectColor → Input.Color.rgb // Output - color = vec4(result, 1.0); // vec3 → vec4 - color2 = v_EntityID; + color = vec4(result, u_Albedo.w); // vec3 → vec4 + color2 = u_EntityID; } diff --git a/conanfile.txt b/conanfile.txt index b7fcf28..d325039 100644 --- a/conanfile.txt +++ b/conanfile.txt @@ -4,6 +4,7 @@ spdlog/1.16.0 entt/3.16.0 yaml-cpp/0.8.0 joltphysics/5.2.0 +fastgltf/0.9.0 [generators] CMakeDeps diff --git a/editor/include/editor.hpp b/editor/include/editor.hpp index 3eef8ca..fe80219 100755 --- a/editor/include/editor.hpp +++ b/editor/include/editor.hpp @@ -1,9 +1,12 @@ #ifndef EDITOR_HPP #define EDITOR_HPP -#include #include +#include "open_engine/fastgltf.hpp" +#include "open_engine/logging.hpp" +#include "open_engine/ref_scope.hpp" +#include "open_engine/renderer/model3d.hpp" #include "open_engine/renderer/renderer3d.hpp" #include "open_engine/scene/components.hpp" #include "panels/content_browser.hpp" @@ -129,6 +132,23 @@ namespace OpenEngine { auto& mc2 = cube2.AddComponent(mesh2); mc2.primitive_type = PrimitiveType::Cube; + // ============================================================ + + Entity cube3 = scene->CreateEntity("glb"); + Entity cube4 = scene->CreateEntity("glb2"); + Entity cube5 = scene->CreateEntity("glb2"); + cube3.AddComponent(); + cube4.AddComponent(); + cube5.AddComponent(); + + Ref model = Model3D::Create("./assets/models/cubes.glb"); + Ref model2 = Model3D::Create("./assets/models/cube_legs.glb"); + Ref monkey = Model3D::Create("./assets/models/monkey.glb"); + + cube3.AddComponent(model); + cube3.AddComponent(model2); + cube4.AddComponent(monkey); + /* auto view = scene->GetRegistry().view(); diff --git a/editor/include/editor_component.hpp b/editor/include/editor_component.hpp index 48e6ff5..5e99232 100644 --- a/editor/include/editor_component.hpp +++ b/editor/include/editor_component.hpp @@ -22,6 +22,7 @@ namespace OpenEngine { void SphereShapeOnImGuiRender(entt::registry& registry, entt::entity entity); void BoxShapeOnImGuiRender(entt::registry& registry, entt::entity entity); void PlaneShapeOnImGuiRender(entt::registry& registry, entt::entity entity); + void ModelOnImGuiRender(entt::registry& registry, entt::entity entity); } #endif // EDITOR_COMPONENT_HPP diff --git a/editor/src/editor_component.cpp b/editor/src/editor_component.cpp index 333e0d7..61a374b 100644 --- a/editor/src/editor_component.cpp +++ b/editor/src/editor_component.cpp @@ -2,6 +2,7 @@ #include "open_engine/renderer/renderer3d.hpp" #include "open_engine/scene/components.hpp" #include +#include #include #include #include @@ -295,4 +296,33 @@ namespace OpenEngine { "%.2f", ImGuiSliderFlags_AlwaysClamp); } + + void ModelOnImGuiRender(entt::registry& registry, entt::entity entity) + { + auto& model_comp = registry.get(entity); + + bool opened = ImGui::TreeNodeEx( + (void*)(intptr_t)entity, + ImGuiTreeNodeFlags_None, + "Meshes", + nullptr + ); + + if (opened) { + unsigned int i = 0; + for (auto& mesh : model_comp.model->GetMeshes()) + ImGui::Text("Mesh: %i", i++); + + + ImGui::PushStyleColor(ImGuiCol_ChildBg, {1, 1, 1, 1}); + if (ImGui::BeginChild("Material list")) { + for (auto& mesh : model_comp.model->GetMeshes()) + ImGui::Text("Material: %s", mesh.material.name.c_str()); + ImGui::EndChild(); + } + ImGui::PopStyleColor(); + + ImGui::TreePop(); + } + } } diff --git a/editor/src/panels/scene_hierarchy.cpp b/editor/src/panels/scene_hierarchy.cpp index df755ee..e839cd1 100644 --- a/editor/src/panels/scene_hierarchy.cpp +++ b/editor/src/panels/scene_hierarchy.cpp @@ -28,6 +28,7 @@ namespace OpenEngine { RegisterDrawer("Sphere Shape", &SphereShapeOnImGuiRender); RegisterDrawer("Box Shape", &BoxShapeOnImGuiRender); RegisterDrawer("Plane Shape", &PlaneShapeOnImGuiRender); + RegisterDrawer("Model", &ModelOnImGuiRender); scene = context; selected_context = {}; @@ -81,6 +82,11 @@ namespace OpenEngine { selected_context.AddComponent(); ImGui::CloseCurrentPopup(); } + if (!selected_context.HasComponent()) + if (ImGui::MenuItem("Model")) { + selected_context.AddComponent(); + ImGui::CloseCurrentPopup(); + } } void EntityPopup(Ref& scene) diff --git a/imgui.ini b/imgui.ini index a3d0252..11d10c1 100644 --- a/imgui.ini +++ b/imgui.ini @@ -1,6 +1,6 @@ [Window][WindowOverViewport_11111111] Pos=0,24 -Size=2560,1371 +Size=1272,1363 Collapsed=0 [Window][Debug##Default] @@ -10,31 +10,31 @@ Collapsed=0 [Window][Statistics] Pos=0,24 -Size=224,439 +Size=409,437 Collapsed=0 DockId=0x00000003,0 [Window][Properties] -Pos=2110,24 -Size=450,810 +Pos=822,24 +Size=450,805 Collapsed=0 DockId=0x00000007,0 [Window][Viewport] -Pos=226,61 -Size=1882,964 +Pos=411,61 +Size=409,956 Collapsed=0 DockId=0x00000012,0 [Window][Dear ImGui Demo] -Pos=2110,836 -Size=450,559 +Pos=822,831 +Size=450,556 Collapsed=0 DockId=0x00000008,0 [Window][Scene] -Pos=0,465 -Size=224,930 +Pos=0,463 +Size=409,924 Collapsed=0 DockId=0x00000004,0 @@ -143,8 +143,8 @@ Collapsed=0 DockId=0x00000012,1 [Window][Assets] -Pos=226,1027 -Size=1882,368 +Pos=411,1019 +Size=409,368 Collapsed=0 DockId=0x0000000C,0 @@ -155,18 +155,18 @@ Collapsed=0 DockId=0x0000000F,0 [Window][##play_state_bar] -Pos=226,24 -Size=1882,35 +Pos=411,24 +Size=409,35 Collapsed=0 DockId=0x00000011,0 [Docking][Data] -DockSpace ID=0x08BD597D Window=0x1BBC0F80 Pos=0,24 Size=2560,1371 Split=X +DockSpace ID=0x08BD597D Window=0x1BBC0F80 Pos=0,24 Size=1272,1363 Split=X DockNode ID=0x00000005 Parent=0x08BD597D SizeRef=820,1386 Split=X - DockNode ID=0x00000001 Parent=0x00000005 SizeRef=224,1386 Split=Y Selected=0xE601B12F + DockNode ID=0x00000001 Parent=0x00000005 SizeRef=409,1386 Split=Y Selected=0xE601B12F DockNode ID=0x00000003 Parent=0x00000001 SizeRef=255,417 Selected=0x553E127E DockNode ID=0x00000004 Parent=0x00000001 SizeRef=255,883 Selected=0xE601B12F - DockNode ID=0x00000002 Parent=0x00000005 SizeRef=594,1386 Split=Y Selected=0xC450F867 + DockNode ID=0x00000002 Parent=0x00000005 SizeRef=409,1386 Split=Y Selected=0xC450F867 DockNode ID=0x00000009 Parent=0x00000002 SizeRef=483,784 Split=Y Selected=0xC450F867 DockNode ID=0x0000000B Parent=0x00000009 SizeRef=409,932 Split=X Selected=0xC450F867 DockNode ID=0x0000000D Parent=0x0000000B SizeRef=1080,993 Split=Y Selected=0xC450F867 diff --git a/open_engine/CMakeLists.txt b/open_engine/CMakeLists.txt index 736726e..201c4b2 100644 --- a/open_engine/CMakeLists.txt +++ b/open_engine/CMakeLists.txt @@ -14,6 +14,7 @@ find_package(imgui REQUIRED) find_package(EnTT REQUIRED) find_package(yaml-cpp REQUIRED) find_package(Jolt REQUIRED) +find_package(fastgltf REQUIRED) file(GLOB_RECURSE SRC_FILES "src/*.cpp") file(GLOB IMGUIZMO_SRC_FILES "${CMAKE_SOURCE_DIR}/vendor/ImGuizmo/*.cpp") @@ -63,6 +64,7 @@ target_link_libraries(${PROJECT_EXECUTABLE_NAME} PUBLIC spirv-cross-glsl spirv-cross-reflect Jolt::Jolt + fastgltf::fastgltf ) #target_link_directories(${PROJECT_EXECUTABLE_NAME} PRIVATE diff --git a/open_engine/include/open_engine/fastgltf.hpp b/open_engine/include/open_engine/fastgltf.hpp new file mode 100644 index 0000000..77976f1 --- /dev/null +++ b/open_engine/include/open_engine/fastgltf.hpp @@ -0,0 +1,13 @@ +#ifndef FASTGLTF_HPP +#define FASTGLTF_HPP + +#include "renderer/renderer3d.hpp" +#include "open_engine/ref_scope.hpp" + +namespace OpenEngine { + + Ref TestGLTF(); + +} + +#endif // FASTGLTF_HPP diff --git a/open_engine/include/open_engine/gltf/gltf_model3d.hpp b/open_engine/include/open_engine/gltf/gltf_model3d.hpp new file mode 100644 index 0000000..5831e16 --- /dev/null +++ b/open_engine/include/open_engine/gltf/gltf_model3d.hpp @@ -0,0 +1,38 @@ +#ifndef GLTF_MODEL3D_HPP +#define GLTF_MODEL3D_HPP + +#include "open_engine/renderer/model3d.hpp" + +#include +#include +#include + +namespace OpenEngine { + + class GLTFModel3D : public Model3D + { + public: + GLTFModel3D(const char* path); + + void loadPrimitive(fastgltf::Asset& asset, + fastgltf::Primitive& primitive, + Mesh& out); + virtual const Mesh& GetMesh(int index) const override; + virtual const std::vector& GetMeshes() const override; + + virtual size_t GetMeshCount() const override { return meshes.size(); }; + + virtual std::vector::iterator begin() override { return meshes.begin(); }; + virtual std::vector::iterator end() override { return meshes.end(); }; + + virtual std::vector::const_iterator begin() const override { return meshes.cbegin(); }; + virtual std::vector::const_iterator end() const override { return meshes.end(); }; + + private: + std::string name; + std::vector meshes; + }; + +} + +#endif // GLTF_MODEL3D_HPP diff --git a/open_engine/include/open_engine/renderer/model3d.hpp b/open_engine/include/open_engine/renderer/model3d.hpp new file mode 100644 index 0000000..e7d938b --- /dev/null +++ b/open_engine/include/open_engine/renderer/model3d.hpp @@ -0,0 +1,69 @@ +#ifndef MODEL3D_HPP +#define MODEL3D_HPP + +#include "open_engine/core/uuid.hpp" +#include "open_engine/renderer/vertex_array.hpp" +#include +#include +#include +#include + +namespace OpenEngine { + + struct Material + { + glm::vec4 albedo = { 1.0f, 0.0f, 0.8f, 1.0f }; + float roughness = 1.0f; + float metallic = 1.0f; + float ambient_strength = 1.0f; + float specular_strength = 1.0f; + std::string name = "un-named material"; + }; + + struct MeshVertex + { + glm::vec3 position; + glm::vec3 normal; + glm::vec2 text_coords; + }; + + struct Mesh + { + UUID uuid; + + Material material; + + Ref vertex_array; + Ref vertex_buffer; + Ref index_buffer; + + // TODO: Make them a ptr or something + std::vector vertices; + std::vector indices; + }; + + // TODO: Model3D.Instanciate(); + // Or Model3D.GetVertices() {return iterateaccessorwithindex bla bla bla} + // What data should Model3D hold in the end if it is not a renderable object? + class Model3D + { + public: + virtual ~Model3D() = default; + + static Ref Create(const char* path); + + virtual const Mesh& GetMesh(int index) const = 0; + virtual const std::vector& GetMeshes() const = 0; + + virtual size_t GetMeshCount() const = 0; + + virtual std::vector::iterator begin() = 0; + virtual std::vector::iterator end() = 0; + + virtual std::vector::const_iterator begin() const = 0; + virtual std::vector::const_iterator end() const = 0; + }; + +} + +#endif // MODEL3D_HPP diff --git a/open_engine/include/open_engine/renderer/renderer3d.hpp b/open_engine/include/open_engine/renderer/renderer3d.hpp index 2ee90df..f81f25e 100644 --- a/open_engine/include/open_engine/renderer/renderer3d.hpp +++ b/open_engine/include/open_engine/renderer/renderer3d.hpp @@ -2,9 +2,8 @@ #define RENDERER3D_HPP #include "open_engine/renderer/editor_camera.hpp" -#include "open_engine/renderer/vertex_array.hpp" -#include "open_engine/renderer/buffer.hpp" #include "open_engine/scene/scene_camera.hpp" +#include "open_engine/renderer/model3d.hpp" #include namespace OpenEngine { @@ -18,39 +17,12 @@ namespace OpenEngine { Cube }; - struct MeshVertex - { - glm::vec3 position; - glm::vec4 color; - glm::vec3 normal; - glm::vec2 text_coords; - uint32_t id = -1; - }; - - struct Material - { - glm::vec4 albedo = { 1.0f, 1.0f, 1.0f, 1.0f }; - float roughness = 1.0f; - float metallic = 1.0f; - float ambient_strength = 1.0f; - float specular_strength = 1.0f; - }; - - struct Mesh - { - Ref vertex_array; - Ref vertex_buffer; - Ref index_buffer; - - // TODO: Make them a ptr or something - std::vector vertices; - std::vector indices; - }; - Ref CreateMesh(const std::vector& vertices, const std::vector& indices); + void PopulateMesh(Mesh& mesh); Ref CreateCube(uint32_t id = -1); Ref CreateQuad(uint32_t id = -1, bool back_face = false); + // ================================================== class Renderer3D @@ -65,6 +37,12 @@ namespace OpenEngine { static void DrawMesh(const Ref& mesh, Material& material, const glm::mat4& transform); + static void DrawMesh(const Ref& mesh, Material& material, + const glm::mat4& transform, + uint32_t entity_id); + static void DrawModel(const Ref& model, + const glm::mat4& transform, + uint32_t entity_id); }; } diff --git a/open_engine/include/open_engine/scene/components.hpp b/open_engine/include/open_engine/scene/components.hpp index c5d4aa8..950b8b5 100644 --- a/open_engine/include/open_engine/scene/components.hpp +++ b/open_engine/include/open_engine/scene/components.hpp @@ -7,6 +7,8 @@ #include "open_engine/renderer/renderer3d.hpp" #include "open_engine/physics.hpp" #include "open_engine/core/uuid.hpp" +#include "open_engine/ref_scope.hpp" +#include "open_engine/renderer/model3d.hpp" #include #include @@ -147,16 +149,36 @@ namespace OpenEngine { struct BoxShapeComponent { glm::vec3 size = { 1.0f, 1.0f, 1.0f }; + + BoxShapeComponent() = default; + BoxShapeComponent(const BoxShapeComponent&) = default; }; struct SphereShapeComponent { float radius = 1.0f; + + SphereShapeComponent() = default; + SphereShapeComponent(const SphereShapeComponent&) = default; }; struct PlaneShapeComponent { float extent = 1.0f; + + PlaneShapeComponent() = default; + PlaneShapeComponent(const PlaneShapeComponent&) = default; + }; + + struct ModelComponent + { + Ref model; + + ModelComponent() = default; + ModelComponent(const ModelComponent&) = default; + ModelComponent(Ref& model) + : model(model) + {} }; } diff --git a/open_engine/src/open_engine/fastgltf.cpp b/open_engine/src/open_engine/fastgltf.cpp new file mode 100644 index 0000000..e642cef --- /dev/null +++ b/open_engine/src/open_engine/fastgltf.cpp @@ -0,0 +1,86 @@ +#include + +#include "logging.hpp" +#include +#include "ref_scope.hpp" + +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace OpenEngine { + + void loadPrimitive(fastgltf::Asset& asset, + fastgltf::Primitive& primitive, + Mesh& out) + { + if (primitive.indicesAccessor.has_value()) { + auto& accessor = asset.accessors[primitive.indicesAccessor.value()]; + out.indices.resize(accessor.count); + + fastgltf::iterateAccessorWithIndex(asset, accessor, + [&](uint32_t index, size_t i) { + out.indices[i] = index; + }); + } + + { + auto* position_iterator = primitive.findAttribute("POSITION"); + auto& accessor = asset.accessors[position_iterator->accessorIndex]; + out.vertices.resize(accessor.count); + + fastgltf::iterateAccessorWithIndex(asset, accessor, + [&](glm::vec3 pos, size_t i) { + out.vertices[i].position = pos; + }); + } + + if (auto* normal_iterator = primitive.findAttribute("NORMAL"); + normal_iterator != primitive.attributes.end()) { + auto& accessor = asset.accessors[normal_iterator->accessorIndex]; + + fastgltf::iterateAccessorWithIndex(asset, accessor, + [&](glm::vec3 norm, size_t i) { + out.vertices[i].normal = norm; + }); + } + + { + if (primitive.materialIndex.has_value()) { + auto& material = asset.materials[primitive.materialIndex.value()]; + auto& pbr = material.pbrData; + + auto& c = pbr.baseColorFactor; + } + } + } + + Ref TestGLTF() + { + fastgltf::Parser parser; + Ref new_mesh = CreateRef(); + + auto data = fastgltf::GltfDataBuffer::FromPath("assets/models/cube.glb"); + if (data.error() != fastgltf::Error::None) + OE_CORE_ERROR("Could not parse model"); + + auto asset = parser.loadGltfBinary(data.get(), ".", + fastgltf::Options::LoadExternalBuffers + ); + if (asset.error() != fastgltf::Error::None) + OE_CORE_ERROR("Could not optain asset"); + + for (auto& mesh : asset->meshes) + for (auto& primitive : mesh.primitives) + loadPrimitive(asset.get(), primitive, *new_mesh); + + return new_mesh; + } + +} diff --git a/open_engine/src/open_engine/gltf/gltf_model3d.cpp b/open_engine/src/open_engine/gltf/gltf_model3d.cpp new file mode 100644 index 0000000..1329676 --- /dev/null +++ b/open_engine/src/open_engine/gltf/gltf_model3d.cpp @@ -0,0 +1,137 @@ +#include "logging.hpp" +#include + +#include + +#include +#include +#include +#include + +namespace OpenEngine { + + void PopulateMesh(Mesh& mesh) + { + mesh.vertex_array = VertexArray::Create(); + + mesh.vertex_buffer = VertexBuffer::Create(mesh.vertices.size() * sizeof(MeshVertex)); + mesh.vertex_buffer->SetData(mesh.vertices.data(), mesh.vertices.size() * sizeof(MeshVertex)); + + BufferLayout layout = { + { ShaderDataType::Float3, "a_Position" }, + { ShaderDataType::Float3, "a_Normal" }, + { ShaderDataType::Float2, "a_TexCoord" } + }; + + mesh.vertex_buffer->SetLayout(layout); + mesh.vertex_array->AddVertexBuffer(mesh.vertex_buffer); + + mesh.index_buffer = IndexBuffer::Create(mesh.indices.data(), mesh.indices.size()); + mesh.vertex_array->SetIndexBuffer(mesh.index_buffer); + } + + Ref CreateMesh(const std::vector& vertices, + const std::vector& indices) + { + Ref mesh = CreateRef(); + + mesh->vertices = vertices; + mesh->indices = indices; + + PopulateMesh(*mesh); + + return mesh; + } + + void GLTFModel3D::loadPrimitive(fastgltf::Asset& asset, + fastgltf::Primitive& primitive, + Mesh& out) + { + if (primitive.indicesAccessor.has_value()) { + auto& accessor = asset.accessors[primitive.indicesAccessor.value()]; + out.indices.resize(accessor.count); + + fastgltf::iterateAccessorWithIndex(asset, accessor, + [&](uint32_t index, size_t i) { + out.indices[i] = index; + }); + } + + { + auto* position_iterator = primitive.findAttribute("POSITION"); + auto& accessor = asset.accessors[position_iterator->accessorIndex]; + out.vertices.resize(accessor.count); + + fastgltf::iterateAccessorWithIndex(asset, accessor, + [&](glm::vec3 pos, size_t i) { + out.vertices[i].position = pos; + }); + } + + if (auto* normal_iterator = primitive.findAttribute("NORMAL"); + normal_iterator != primitive.attributes.end()) { + auto& accessor = asset.accessors[normal_iterator->accessorIndex]; + + fastgltf::iterateAccessorWithIndex(asset, accessor, + [&](glm::vec3 norm, size_t i) { + out.vertices[i].normal = norm; + }); + } + + { + if (primitive.materialIndex.has_value()) { + auto& material = asset.materials[primitive.materialIndex.value()]; + auto& pbr = material.pbrData; + + auto& color = pbr.baseColorFactor; + auto& roughness = pbr.roughnessFactor; + auto& metallic = pbr.metallicFactor; + + out.material.name = material.name; + out.material.albedo = glm::vec4(color[0], color[1], color[2], color[3]); + out.material.roughness = roughness; + out.material.metallic = metallic; + } + } + } + + GLTFModel3D::GLTFModel3D(const char* path) + { + fastgltf::Parser parser; + + auto data = fastgltf::GltfDataBuffer::FromPath(path); + if (data.error() != fastgltf::Error::None) + OE_CORE_ERROR("Could not parse model"); + + auto asset = parser.loadGltfBinary(data.get(), ".", + fastgltf::Options::LoadExternalBuffers + ); + if (asset.error() != fastgltf::Error::None) + OE_CORE_ERROR("Could not optain asset"); + + + for (auto& mesh : asset->meshes) { + name = mesh.name; + + for (auto& primitive : mesh.primitives) { + Mesh prim_mesh; + + loadPrimitive(asset.get(), primitive, prim_mesh); + PopulateMesh(prim_mesh); + + meshes.emplace_back(prim_mesh); + } + } + }; + + const Mesh& GLTFModel3D::GetMesh(int index) const + { + return meshes[index]; + } + + const std::vector& GLTFModel3D::GetMeshes() const + { + return meshes; + } + +} diff --git a/open_engine/src/open_engine/renderer/model3d.cpp b/open_engine/src/open_engine/renderer/model3d.cpp new file mode 100644 index 0000000..4f58a50 --- /dev/null +++ b/open_engine/src/open_engine/renderer/model3d.cpp @@ -0,0 +1,19 @@ +#include + +#include + +#include +#include +#include + + +namespace OpenEngine { + + Ref Model3D::Create(const char* path) + { + OE_PROFILE_FUNCTION(); + + return CreateRef(path); + } + +} diff --git a/open_engine/src/open_engine/renderer/renderer3d.cpp b/open_engine/src/open_engine/renderer/renderer3d.cpp index 291bfb7..75c04f9 100644 --- a/open_engine/src/open_engine/renderer/renderer3d.cpp +++ b/open_engine/src/open_engine/renderer/renderer3d.cpp @@ -23,33 +23,6 @@ namespace OpenEngine { // SHOULD BE MOVED ================================== - Ref CreateMesh(const std::vector& vertices, - const std::vector& indices) - { - Ref mesh = CreateRef(); - mesh->vertices = vertices; - mesh->indices = indices; - - mesh->vertex_array = VertexArray::Create(); - - mesh->vertex_buffer = VertexBuffer::Create(vertices.size() * sizeof(MeshVertex)); - mesh->vertex_buffer->SetData(vertices.data(), vertices.size() * sizeof(MeshVertex)); - - BufferLayout layout = { - { ShaderDataType::Float3, "a_Position" }, - { ShaderDataType::Float4, "a_Color" }, - { ShaderDataType::Float3, "a_Normal" }, - { ShaderDataType::Float2, "a_TexCoord" }, - { ShaderDataType::Int, "a_EntityID"} - }; - mesh->vertex_buffer->SetLayout(layout); - mesh->vertex_array->AddVertexBuffer(mesh->vertex_buffer); - - mesh->index_buffer = IndexBuffer::Create(indices.data(), indices.size()); - mesh->vertex_array->SetIndexBuffer(mesh->index_buffer); - - return mesh; - } Ref CreateQuad(uint32_t id, bool back_face) { @@ -61,16 +34,16 @@ namespace OpenEngine { if (back_face) { vertices = { // Front face (normal 0, 0, 1) - {{-0.5f, -0.5f, 0.0f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,0,1}, {0,0}, id}, - {{-0.5f, 0.5f, 0.0f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,0,1}, {0,1}, id}, - {{ 0.5f, 0.5f, 0.0f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,0,1}, {1,1}, id}, - {{ 0.5f, -0.5f, 0.0f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,0,1}, {1,0}, id}, + {{-0.5f, -0.5f, 0.0f}, {0,0,1}, {0,0}}, + {{-0.5f, 0.5f, 0.0f}, {0,0,1}, {0,1}}, + {{ 0.5f, 0.5f, 0.0f}, {0,0,1}, {1,1}}, + {{ 0.5f, -0.5f, 0.0f}, {0,0,1}, {1,0}}, // Back face (normal 0, 0, -1) - {{-0.5f, -0.5f, -0.0f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,0,-1}, {0,0}, id}, - {{-0.5f, 0.5f, -0.0f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,0,-1}, {0,1}, id}, - {{ 0.5f, 0.5f, -0.0f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,0,-1}, {1,1}, id}, - {{ 0.5f, -0.5f, -0.0f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,0,-1}, {1,0}, id} + {{-0.5f, -0.5f, -0.0f}, {0,0,-1}, {0,0}}, + {{-0.5f, 0.5f, -0.0f}, {0,0,-1}, {0,1}}, + {{ 0.5f, 0.5f, -0.0f}, {0,0,-1}, {1,1}}, + {{ 0.5f, -0.5f, -0.0f}, {0,0,-1}, {1,0}} }; indices = { @@ -82,10 +55,10 @@ namespace OpenEngine { } else { vertices = { // Front face (normal 0, 0, 1) - {{-0.5f, -0.5f, 0.0f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,0,1}, {0,0}, id}, - {{-0.5f, 0.5f, 0.0f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,0,1}, {0,1}, id}, - {{ 0.5f, 0.5f, 0.0f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,0,1}, {1,1}, id}, - {{ 0.5f, -0.5f, 0.0f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,0,1}, {1,0}, id} + {{-0.5f, -0.5f, 0.0f}, {0,0,1}, {0,0}}, + {{-0.5f, 0.5f, 0.0f}, {0,0,1}, {0,1}}, + {{ 0.5f, 0.5f, 0.0f}, {0,0,1}, {1,1}}, + {{ 0.5f, -0.5f, 0.0f}, {0,0,1}, {1,0}} }; indices = { @@ -103,40 +76,40 @@ namespace OpenEngine { OE_CORE_DEBUG("Creating cube with id {}.", id); std::vector vertices = { // Front face (normal 0, 0, 1) - {{-0.5f, -0.5f, 0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,0,1}, {0,0}, id}, - {{-0.5f, 0.5f, 0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,0,1}, {0,1}, id}, - {{ 0.5f, 0.5f, 0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,0,1}, {1,1}, id}, - {{ 0.5f, -0.5f, 0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,0,1}, {1,0}, id}, + {{-0.5f, -0.5f, 0.5f}, {0,0,1}, {0,0}}, + {{-0.5f, 0.5f, 0.5f}, {0,0,1}, {0,1}}, + {{ 0.5f, 0.5f, 0.5f}, {0,0,1}, {1,1}}, + {{ 0.5f, -0.5f, 0.5f}, {0,0,1}, {1,0}}, // Back face (normal 0, 0, -1) - {{-0.5f, -0.5f, -0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,0,-1}, {0,0}, id}, - {{-0.5f, 0.5f, -0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,0,-1}, {0,1}, id}, - {{ 0.5f, 0.5f, -0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,0,-1}, {1,1}, id}, - {{ 0.5f, -0.5f, -0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,0,-1}, {1,0}, id}, + {{-0.5f, -0.5f, -0.5f}, {0,0,-1}, {0,0}}, + {{-0.5f, 0.5f, -0.5f}, {0,0,-1}, {0,1}}, + {{ 0.5f, 0.5f, -0.5f}, {0,0,-1}, {1,1}}, + {{ 0.5f, -0.5f, -0.5f}, {0,0,-1}, {1,0}}, // Left face (normal -1, 0, 0) - {{-0.5f, -0.5f, -0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {-1,0,0}, {0,0}, id}, - {{-0.5f, 0.5f, -0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {-1,0,0}, {0,1}, id}, - {{-0.5f, 0.5f, 0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {-1,0,0}, {1,1}, id}, - {{-0.5f, -0.5f, 0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {-1,0,0}, {1,0}, id}, + {{-0.5f, -0.5f, -0.5f}, {-1,0,0}, {0,0}}, + {{-0.5f, 0.5f, -0.5f}, {-1,0,0}, {0,1}}, + {{-0.5f, 0.5f, 0.5f}, {-1,0,0}, {1,1}}, + {{-0.5f, -0.5f, 0.5f}, {-1,0,0}, {1,0}}, // Right face (normal 1, 0, 0) - {{ 0.5f, -0.5f, -0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {1,0,0}, {0,0}, id}, - {{ 0.5f, 0.5f, -0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {1,0,0}, {0,1}, id}, - {{ 0.5f, 0.5f, 0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {1,0,0}, {1,1}, id}, - {{ 0.5f, -0.5f, 0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {1,0,0}, {1,0}, id}, + {{ 0.5f, -0.5f, -0.5f}, {1,0,0}, {0,0}}, + {{ 0.5f, 0.5f, -0.5f}, {1,0,0}, {0,1}}, + {{ 0.5f, 0.5f, 0.5f}, {1,0,0}, {1,1}}, + {{ 0.5f, -0.5f, 0.5f}, {1,0,0}, {1,0}}, // Top face (normal 0, 1, 0) - {{-0.5f, 0.5f, -0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,1,0}, {0,0}, id}, - {{-0.5f, 0.5f, 0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,1,0}, {0,1}, id}, - {{ 0.5f, 0.5f, 0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,1,0}, {1,1}, id}, - {{ 0.5f, 0.5f, -0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,1,0}, {1,0}, id}, + {{-0.5f, 0.5f, -0.5f}, {0,1,0}, {0,0}}, + {{-0.5f, 0.5f, 0.5f}, {0,1,0}, {0,1}}, + {{ 0.5f, 0.5f, 0.5f}, {0,1,0}, {1,1}}, + {{ 0.5f, 0.5f, -0.5f}, {0,1,0}, {1,0}}, // Bottom face (normal 0, -1, 0) - {{-0.5f, -0.5f, -0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,-1,0}, {0,0}, id}, - {{-0.5f, -0.5f, 0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,-1,0}, {0,1}, id}, - {{ 0.5f, -0.5f, 0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,-1,0}, {1,1}, id}, - {{ 0.5f, -0.5f, -0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,-1,0}, {1,0}, id}, + {{-0.5f, -0.5f, -0.5f}, {0,-1,0}, {0,0}}, + {{-0.5f, -0.5f, 0.5f}, {0,-1,0}, {0,1}}, + {{ 0.5f, -0.5f, 0.5f}, {0,-1,0}, {1,1}}, + {{ 0.5f, -0.5f, -0.5f}, {0,-1,0}, {1,0}}, }; std::vector indices = { @@ -179,6 +152,8 @@ namespace OpenEngine { Material material_buffer; Ref material_uniform_buffer; + + Ref id_uniform_buffer; }; static Renderer3DData renderer_data; @@ -194,6 +169,7 @@ namespace OpenEngine { renderer_data.camera_uniform_buffer = UniformBuffer::Create(sizeof(Renderer3DData::CameraData), 0); renderer_data.transform_uniform_buffer = UniformBuffer::Create(sizeof(Renderer3DData::TransformData), 1); renderer_data.material_uniform_buffer = UniformBuffer::Create(sizeof(Material), 2); + renderer_data.id_uniform_buffer = UniformBuffer::Create(sizeof(uint32_t), 3); glEnable(GL_DEBUG_OUTPUT); glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); @@ -209,6 +185,7 @@ namespace OpenEngine { renderer_data.camera_uniform_buffer.reset(); renderer_data.transform_uniform_buffer.reset(); renderer_data.material_uniform_buffer.reset(); + renderer_data.id_uniform_buffer.reset(); } void Renderer3D::BeginScene(const SceneCamera& camera, const glm::mat4& transform) @@ -253,4 +230,48 @@ namespace OpenEngine { RenderCommand::DrawIndexed(mesh->vertex_array, mesh->indices.size()); } + + void Renderer3D::DrawMesh(const Ref& mesh, Material& material, + const glm::mat4& transform, + uint32_t entity_id) + { + OE_PROFILE_FUNCTION(); + + renderer_data.color_shader_3d->Bind(); + + renderer_data.transform_buffer.transform = transform; + renderer_data.transform_uniform_buffer->SetData(&renderer_data.transform_buffer, sizeof(Renderer3DData::TransformData)); + + renderer_data.material_buffer = material; + renderer_data.material_uniform_buffer->SetData(&renderer_data.material_buffer, sizeof(Material)); + + renderer_data.id_uniform_buffer->SetData(&entity_id, sizeof(uint32_t)); + + mesh->vertex_array->Bind(); + + RenderCommand::DrawIndexed(mesh->vertex_array, mesh->indices.size()); + } + + void Renderer3D::DrawModel(const Ref& model, + const glm::mat4& transform, + uint32_t entity_id) + { + OE_PROFILE_FUNCTION(); + + renderer_data.color_shader_3d->Bind(); + + renderer_data.transform_buffer.transform = transform; + renderer_data.transform_uniform_buffer->SetData(&renderer_data.transform_buffer, sizeof(Renderer3DData::TransformData)); + + for (auto& mesh : *model) { + renderer_data.material_buffer = mesh.material; + renderer_data.material_uniform_buffer->SetData(&renderer_data.material_buffer, sizeof(Material)); + + renderer_data.id_uniform_buffer->SetData(&entity_id, sizeof(uint32_t)); + + mesh.vertex_array->Bind(); + + RenderCommand::DrawIndexed(mesh.vertex_array, mesh.indices.size()); + } + } } diff --git a/open_engine/src/open_engine/scene/scene.cpp b/open_engine/src/open_engine/scene/scene.cpp index f691578..48fdde1 100755 --- a/open_engine/src/open_engine/scene/scene.cpp +++ b/open_engine/src/open_engine/scene/scene.cpp @@ -1,6 +1,7 @@ #include "logging.hpp" #include "physics.hpp" #include "ref_scope.hpp" +#include "renderer/model3d.hpp" #include #include #include @@ -264,7 +265,17 @@ namespace OpenEngine { material = _entity.GetComponents().material; if (mesh.mesh) - Renderer3D::DrawMesh(mesh.mesh, material, GetTransformFromComp(transform)); + Renderer3D::DrawMesh(mesh.mesh, material, GetTransformFromComp(transform), (uint32_t)_entity); + } + + auto model_view = registry.view(); + + for (const auto& entity : model_view) { + auto [transform, model_comp] = model_view.get(entity); + + Entity _entity(entity, this); + + Renderer3D::DrawModel(model_comp.model, GetTransformFromComp(transform), (uint32_t)_entity); } Renderer3D::EndScene(); @@ -363,4 +374,9 @@ namespace OpenEngine { void Scene::OnComponentAdded(Entity entity, PlaneShapeComponent& component) { } + + template<> + void Scene::OnComponentAdded(Entity entity, ModelComponent& component) + { + } } diff --git a/open_engine/src/open_engine/scene/scene_serializer.cpp b/open_engine/src/open_engine/scene/scene_serializer.cpp index 6213720..502095a 100644 --- a/open_engine/src/open_engine/scene/scene_serializer.cpp +++ b/open_engine/src/open_engine/scene/scene_serializer.cpp @@ -93,8 +93,7 @@ namespace OpenEngine { out << YAML::BeginMap; out << YAML::Key << "Entity" << YAML::Value << entity.GetUUID(); // Needs random - if (entity.HasComponent()) - { + if (entity.HasComponent()) { out << YAML::Key << "TagComponent"; out << YAML::BeginMap; // TagComponent @@ -104,8 +103,7 @@ namespace OpenEngine { out << YAML::EndMap; // TagComponent } - if (entity.HasComponent()) - { + if (entity.HasComponent()) { out << YAML::Key << "TransformComponent"; out << YAML::BeginMap; // TransformComponent @@ -141,8 +139,7 @@ namespace OpenEngine { out << YAML::EndMap; // CameraComponent } - if (entity.HasComponent()) - { + if (entity.HasComponent()) { out << YAML::Key << "SpriteRendererComponent"; out << YAML::BeginMap; // SpriteRendererComponent @@ -266,8 +263,7 @@ namespace OpenEngine { OE_CORE_TRACE("Deserializing scene '{0}'", sceneName); auto entities = data["Entities"]; - if (entities) - { + if (entities) { for (auto entity : entities) { uint64_t uuid = entity["Entity"].as(); @@ -282,8 +278,7 @@ namespace OpenEngine { Entity deserializedEntity = context->CreateEntityWithUUID(uuid, name); auto transformComponent = entity["TransformComponent"]; - if (transformComponent) - { + if (transformComponent) { auto& tc = deserializedEntity.AddComponent(); tc.translation = transformComponent["Translation"].as(); tc.rotation = transformComponent["Rotation"].as(); @@ -291,8 +286,7 @@ namespace OpenEngine { } auto cameraComponent = entity["CameraComponent"]; - if (cameraComponent) - { + if (cameraComponent) { auto& cc = deserializedEntity.AddComponent(); auto camera_props = cameraComponent["Camera"]; @@ -311,15 +305,13 @@ namespace OpenEngine { } auto spriteRendererComponent = entity["SpriteRendererComponent"]; - if (spriteRendererComponent) - { + if (spriteRendererComponent) { auto& src = deserializedEntity.AddComponent(); src.color = spriteRendererComponent["Color"].as(); } auto mesh_component = entity["MeshComponent"]; - if (mesh_component) - { + if (mesh_component) { auto& mesh = deserializedEntity.AddComponent(); mesh.primitive_type = (PrimitiveType)mesh_component["MeshType"].as(); switch (mesh.primitive_type) { @@ -388,6 +380,7 @@ namespace OpenEngine { return true; } + bool SceneSerializer::DeserializeRuntime(const std::string& file_path) { OE_CORE_ASSERT(false, "Not implemented yet");