diff --git a/.github/demo/models.png b/.github/demo/models_0.png similarity index 100% rename from .github/demo/models.png rename to .github/demo/models_0.png diff --git a/.github/demo/models_1.png b/.github/demo/models_1.png new file mode 100644 index 0000000..b87504e Binary files /dev/null and b/.github/demo/models_1.png differ diff --git a/Engine/src/Renderer/Material.cpp b/Engine/src/Renderer/Material.cpp index b1eb45b..0045107 100644 --- a/Engine/src/Renderer/Material.cpp +++ b/Engine/src/Renderer/Material.cpp @@ -18,7 +18,7 @@ constexpr const char* kDefaultTextureMapNames[Material::TextureSlot::Count] = { "texture_transparency" }; -void Material::SetTexture(const TextureSlot slot, const std::string& name, const SharedPtr& texture) +void Material::SetTexture(const TextureSlot slot, const std::string& name, SharedPtr texture) { auto& map = m_textures[slot]; map.name = name; @@ -27,10 +27,28 @@ void Material::SetTexture(const TextureSlot slot, const std::string& name, const void Material::SetTexture(const TextureSlot slot, const std::string& name) { + if (name.empty()) { + EL_CORE_ERROR("Failed to set material texture, texture name is empty."); + return; + } + auto& map = m_textures[slot]; map.name = name; } +void Material::SetTexture(const TextureSlot slot, const std::string& name, const std::string& dir, bool async) +{ + if (name.empty()) { + EL_CORE_ERROR("Failed to set material texture, texture name is empty."); + return; + } + + auto& map = m_textures[slot]; + map.name = name; + + LoadTexture(dir, async, map, slot); +} + void Material::LoadTextures(const std::string& dir, const bool async) { for (int i = 0; i < TextureSlot::Count; ++i) { @@ -83,17 +101,6 @@ void Material::ApplyMaterial(const SharedPtr& shader) const shader->SetFloat("u_Material.shininess", m_shininess); } -void Material::ResetMaterial() const -{ - // Unbind textures - for (auto& textureMap : m_textures) { - if (!textureMap.texturePtr) - continue; - - textureMap.texturePtr->Unbind(); - } -} - void Material::LoadTexture(const std::string& dir, const bool async, Material::TextureMap& map, Material::TextureSlot slot) { auto readyTexturePtr = textures::Get(map.name); diff --git a/Engine/src/Renderer/Material.h b/Engine/src/Renderer/Material.h index 17850bd..bb893ad 100644 --- a/Engine/src/Renderer/Material.h +++ b/Engine/src/Renderer/Material.h @@ -23,9 +23,34 @@ class Material { }; public: - void SetTexture(const TextureSlot slot, const std::string& name, const SharedPtr& texture); + /** + * Set already loaded texture texture to the slot + * + * @param slot Texture slot + * @param name Texture name + * @param texture already loaded texture pointer + */ + void SetTexture(const TextureSlot slot, const std::string& name, SharedPtr texture); + + /** + * Set texture info to the slot, texture will be loaded on LoadTextures function call + * + * @param slot Texture slot + * @param name Texture name + */ void SetTexture(const TextureSlot slot, const std::string& name); + /** + * Set texture info to the slot and immediately call loading + * + * @param slot Texture slot + * @param name Texture name + * @param dir Texture path + * @param async Async texture loading (true by default) + */ + void SetTexture(const TextureSlot slot, const std::string& name, const std::string& dir, bool async); + + // Load all textures void LoadTextures(const std::string& dir, const bool async); void SetAmbientColor(const lia::vec3& color); @@ -41,7 +66,6 @@ class Material { float GetShininess() const { return m_shininess; } void ApplyMaterial(const SharedPtr& shader) const; - void ResetMaterial() const; private: void LoadTexture(const std::string& dir, const bool async, TextureMap& map, TextureSlot slot); @@ -53,7 +77,7 @@ class Material { lia::vec3 m_specularColor; lia::vec3 m_emissionColor; - float m_shininess { 1.0f }; + float m_shininess { 32.0f }; }; } // namespace elv diff --git a/Engine/src/Renderer/Mesh.cpp b/Engine/src/Renderer/Mesh.cpp index 48c191e..0c60c1b 100644 --- a/Engine/src/Renderer/Mesh.cpp +++ b/Engine/src/Renderer/Mesh.cpp @@ -30,12 +30,13 @@ Mesh::Mesh(const std::vector& vertices, const std::vector& vertices, const std::vector& indices, const std::vector& texturesInfo) { - m_material.LoadTextures(dir, async); - for (auto& submesh : m_submeshes) { - submesh.LoadTextures(dir, async); - } + m_vertices = vertices; + m_indices = indices; + + SetupMesh(); + SetupMaterial(texturesInfo); } void Mesh::AddSubmesh(Mesh&& submesh) @@ -43,12 +44,19 @@ void Mesh::AddSubmesh(Mesh&& submesh) m_submeshes.emplace_back(std::move(submesh)); } +void Mesh::LoadTextures(const std::string& dir, const bool async) +{ + m_material.LoadTextures(dir, async); + for (auto& submesh : m_submeshes) { + submesh.LoadTextures(dir, async); + } +} + void Mesh::Draw(const SharedPtr& shader) const { m_vao->Bind(); m_material.ApplyMaterial(shader); RenderCommand::DrawIndexed(m_vao, 0, m_topology); - m_material.ResetMaterial(); // draw submeshes for (auto& submesh : m_submeshes) { diff --git a/Engine/src/Renderer/Mesh.h b/Engine/src/Renderer/Mesh.h index 7bb308d..7d36fd4 100644 --- a/Engine/src/Renderer/Mesh.h +++ b/Engine/src/Renderer/Mesh.h @@ -28,16 +28,16 @@ class Mesh { virtual ~Mesh() = default; + void SetInfo(const std::vector& vertices, const std::vector& indices, const std::vector& texturesInfo); void Draw(const SharedPtr& shader) const; + void AddSubmesh(Mesh&& submesh); void LoadTextures(const std::string& dir, const bool async); - void AddSubmesh(Mesh&& submesh); + void SetTopology(const RenderTopology topology) { m_topology = topology; } Material& GetMaterial() { return m_material; } - void SetTopology(const RenderTopology topology) { m_topology = topology; } - private: void SetupMesh(); void SetupMaterial(const std::vector& texturesInfo); diff --git a/Engine/src/Resources/MeshLibrary.cpp b/Engine/src/Resources/MeshLibrary.cpp index d3d5f2f..1961e6a 100644 --- a/Engine/src/Resources/MeshLibrary.cpp +++ b/Engine/src/Resources/MeshLibrary.cpp @@ -20,11 +20,11 @@ constexpr float PI = 3.14159265359f; constexpr float TAU = 6.28318530717f; // -static void LoadMeshFromFile(std::vector& loadedMeshesInfo, const std::string& meshName, const std::string& meshPath) +static void LoadMeshFromFile(std::vector& loadedMeshesInfo, const std::string& meshName, const std::string& meshPath, SharedPtr root) { LoadedMeshesInfo info; info.name = meshName; - info.texturesDir = meshPath; + info.root = root; ImportModel(meshPath, info); @@ -57,7 +57,7 @@ void MeshLibrary::Shutdown() m_futures.clear(); } -void MeshLibrary::LoadMesh(const std::string& name, const std::string& path) +void MeshLibrary::LoadMesh(const std::string& name, const std::string& path, SharedPtr root) { // check whether we already loaded this mesh auto it = m_meshes.find(name); @@ -69,7 +69,7 @@ void MeshLibrary::LoadMesh(const std::string& name, const std::string& path) if (inProgressIt == m_meshLoadingInProgress.end()) { m_meshLoadingInProgress.insert(name); - m_futures.emplace_back(std::async(std::launch::async, LoadMeshFromFile, std::ref(m_loadedMeshes), name, path)); + m_futures.emplace_back(std::async(std::launch::async, LoadMeshFromFile, std::ref(m_loadedMeshes), name, path, root)); } return; } @@ -86,13 +86,14 @@ SharedPtr MeshLibrary::GetMesh(const std::string& name) const void MeshLibrary::ProcessMeshInfo(const LoadedMeshesInfo& meshesInfo) { // process mesh and submeshes - SharedPtr root = nullptr; + bool rootInited = false; for (auto meshInfo : meshesInfo.meshes) { - if (root) { - root->AddSubmesh({ meshInfo.vertices, meshInfo.indices, meshInfo.textures }); + if (rootInited) { + meshesInfo.root->AddSubmesh({ meshInfo.vertices, meshInfo.indices, meshInfo.textures }); } else { - root = MakeSharedPtr(meshInfo.vertices, meshInfo.indices, std::move(meshInfo.textures)); - m_meshes.insert({ meshesInfo.name, root }); + meshesInfo.root->SetInfo(meshInfo.vertices, meshInfo.indices, std::move(meshInfo.textures)); + m_meshes.insert({ meshesInfo.name, meshesInfo.root }); + rootInited = true; } } events::TriggerEvent(events::MeshLoadedEvent { meshesInfo.name }, string_id(meshesInfo.name)); diff --git a/Engine/src/Resources/MeshLibrary.h b/Engine/src/Resources/MeshLibrary.h index 3682949..afa15c6 100644 --- a/Engine/src/Resources/MeshLibrary.h +++ b/Engine/src/Resources/MeshLibrary.h @@ -15,7 +15,7 @@ class MeshLibrary { void Update(); void Shutdown(); - void LoadMesh(const std::string& name, const std::string& path); + void LoadMesh(const std::string& name, const std::string& path, SharedPtr root); SharedPtr GetMesh(const std::string& name) const; diff --git a/Engine/src/Resources/ModelImporter.cpp b/Engine/src/Resources/ModelImporter.cpp index 93e01c2..9b27b10 100644 --- a/Engine/src/Resources/ModelImporter.cpp +++ b/Engine/src/Resources/ModelImporter.cpp @@ -87,7 +87,8 @@ void ProcessNode(aiNode* node, const aiScene* scene, LoadedMeshesInfo& loadedMes void ImportModel(const std::string& path, LoadedMeshesInfo& info) { - PROFILE(fmt::format("ImportMesh {} : ", path)); + EL_CORE_INFO("Model {} loading...", path); + PROFILE(fmt::format("Model {} is loaded: ", path)); Assimp::Importer importer; const aiScene* scene = importer.ReadFile(path, aiProcess_Triangulate); @@ -98,7 +99,7 @@ void ImportModel(const std::string& path, LoadedMeshesInfo& info) } { - PROFILE_SCOPE("Process nodes in: "); + PROFILE_SCOPE(fmt::format("Process model {} nodes: ", path)); ProcessNode(scene->mRootNode, scene, info); } } diff --git a/Engine/src/Resources/ModelImporter.h b/Engine/src/Resources/ModelImporter.h index c1cfa60..ed7854a 100644 --- a/Engine/src/Resources/ModelImporter.h +++ b/Engine/src/Resources/ModelImporter.h @@ -12,8 +12,7 @@ struct LoadedMeshInfo { struct LoadedMeshesInfo { std::string name; - std::string texturesDir; - + SharedPtr root; std::vector meshes; }; diff --git a/Engine/src/Scene/Components/StaticMeshComponent.cpp b/Engine/src/Scene/Components/StaticMeshComponent.cpp index 9b701af..d1bca23 100644 --- a/Engine/src/Scene/Components/StaticMeshComponent.cpp +++ b/Engine/src/Scene/Components/StaticMeshComponent.cpp @@ -10,7 +10,6 @@ #include "Events/MeshEvent.h" namespace elv { -#pragma optimize("", off) void StaticMeshComponent::LoadMesh(const RenderTopology topology) { if (!m_meshName.empty()) { @@ -21,7 +20,11 @@ void StaticMeshComponent::LoadMesh(const RenderTopology topology) } else if (m_meshPath.empty()) { EL_CORE_WARN("Failed to set mesh to the Static Mesh Component, mesh path is empty"); } else { - gMeshLibrary.LoadMesh(m_meshName, m_meshPath); + m_meshPtr = MakeSharedPtr(); + m_meshPtr->SetTopology(topology); + + gMeshLibrary.LoadMesh(m_meshName, m_meshPath, m_meshPtr); + events::Subscribe([&](const events::MeshLoadedEvent& e) { if (e.meshName == m_meshName) { m_meshPtr = gMeshLibrary.GetMesh(m_meshName); @@ -38,4 +41,10 @@ void StaticMeshComponent::LoadMesh(const RenderTopology topology) } } } + +void StaticMeshComponent::AddMaterialTexture(const Material::TextureSlot slot, const std::string& name, const std::string& path, bool async) +{ + auto& material = m_meshPtr->GetMaterial(); + material.SetTexture(slot, name, path, async); +} } // namespace elv diff --git a/Engine/src/Scene/Components/StaticMeshComponent.h b/Engine/src/Scene/Components/StaticMeshComponent.h index 705b98d..8c1ce4e 100644 --- a/Engine/src/Scene/Components/StaticMeshComponent.h +++ b/Engine/src/Scene/Components/StaticMeshComponent.h @@ -1,5 +1,6 @@ #pragma once +#include "Renderer/Material.h" #include "Renderer/RenderTopology.h" namespace elv { @@ -31,6 +32,8 @@ class StaticMeshComponent { const SharedPtr& GetMeshPtr() const { return m_meshPtr; } + void AddMaterialTexture(const Material::TextureSlot slot, const std::string& name, const std::string& path, bool async = true); + private: void LoadMesh(const RenderTopology topology); diff --git a/README.md b/README.md index bb002d0..6ccafd2 100644 --- a/README.md +++ b/README.md @@ -118,4 +118,4 @@ You can modify configure file to enable/disable the following cmake options: | [irrKlang](https://www.ambiera.com/irrklang/) | sound library | | [fmt](https://github.com/fmtlib/fmt) | formatting library | | [freetype](https://freetype.org/) | fonts rendering | -| [assimp](https://github.com/assimp/assimp) | 3D moodel loading | +| [assimp](https://github.com/assimp/assimp) | 3D model loading | diff --git a/Sandbox3D/assets/models/cerberus/Cerberus.tbscene b/Sandbox3D/assets/models/cerberus/Cerberus.tbscene deleted file mode 100644 index 6cdd757..0000000 Binary files a/Sandbox3D/assets/models/cerberus/Cerberus.tbscene and /dev/null differ diff --git a/Sandbox3D/assets/models/cerberus/Textures/Raw/Cerberus_AO.tga b/Sandbox3D/assets/models/cerberus/Textures/Raw/Cerberus_AO.tga deleted file mode 100644 index 7fb99db..0000000 Binary files a/Sandbox3D/assets/models/cerberus/Textures/Raw/Cerberus_AO.tga and /dev/null differ diff --git a/Sandbox3D/assets/models/cerberus/Textures/Raw/Cerberus_M.tga b/Sandbox3D/assets/models/cerberus/Textures/Raw/Cerberus_M.tga deleted file mode 100644 index dfe249a..0000000 Binary files a/Sandbox3D/assets/models/cerberus/Textures/Raw/Cerberus_M.tga and /dev/null differ diff --git a/Sandbox3D/assets/models/cerberus/Textures/Raw/Cerberus_N.tga b/Sandbox3D/assets/models/cerberus/Textures/Raw/Cerberus_N.tga deleted file mode 100644 index f019de1..0000000 Binary files a/Sandbox3D/assets/models/cerberus/Textures/Raw/Cerberus_N.tga and /dev/null differ diff --git a/Sandbox3D/assets/models/cerberus/Textures/Raw/Cerberus_UV.tga b/Sandbox3D/assets/models/cerberus/Textures/Raw/Cerberus_UV.tga deleted file mode 100644 index 5d3720c..0000000 Binary files a/Sandbox3D/assets/models/cerberus/Textures/Raw/Cerberus_UV.tga and /dev/null differ diff --git a/Sandbox3D/assets/models/cerberus/Textures/Raw/Masks.psd b/Sandbox3D/assets/models/cerberus/Textures/Raw/Masks.psd deleted file mode 100644 index adfd6e2..0000000 Binary files a/Sandbox3D/assets/models/cerberus/Textures/Raw/Masks.psd and /dev/null differ diff --git a/Sandbox3D/src/MeshModelSandbox.cpp b/Sandbox3D/src/MeshModelSandbox.cpp index 45ca60f..3e7973b 100644 --- a/Sandbox3D/src/MeshModelSandbox.cpp +++ b/Sandbox3D/src/MeshModelSandbox.cpp @@ -1,13 +1,10 @@ #include "MeshModelSandbox.h" #include -#include #include - -#include - #include #include +#include #if EDITOR_MODE # include @@ -19,22 +16,8 @@ const int kCubesAmount = 1; MeshModelSandbox::MeshModelSandbox() : m_cameraController(45.0f, 1280.0f / 720.0f, 0.1f, 1000.0f) , m_lightCubeMesh(elv::gMeshLibrary.GetMesh("sphere")) - , m_textureLoadedCallback([this](const elv::events::TextureLoadedEvent& e) { OnTextureLoaded(e); }) { - // load textures - const uint64_t hash = elv::string_id("wooden_container"); - elv::events::Subscribe(m_textureLoadedCallback, hash); - elv::textures::Load("wooden_container", fmt::format("{}{}", elv::fileSystem::IMAGES_PATH, "wooden_container.png")); - - const uint64_t hashSpecular = elv::string_id("wooden_container_specular"); - elv::events::Subscribe(m_textureLoadedCallback, hashSpecular); - elv::textures::Load("wooden_container_specular", fmt::format("{}{}", elv::fileSystem::IMAGES_PATH, "wooden_container_specular.png")); - - const uint64_t hashMatrix = elv::string_id("matrix"); - elv::events::Subscribe(m_textureLoadedCallback, hashMatrix); - elv::textures::Load("matrix", fmt::format("{}{}", elv::fileSystem::IMAGES_PATH, "matrix.jpg")); - - // cube shader + // mesh shader m_shader = elv::ShaderManager::Load("textured_cube", "textured_cube.vert", "mesh.frag"); // light setup @@ -53,22 +36,25 @@ MeshModelSandbox::MeshModelSandbox() const auto entity = scene.CreateEntity(); m_models.emplace_back(entity); scene.AddComponent(entity, lia::vec3(2.0f, 2.0f, 0.0f), lia::vec3(0.01f)); - scene.AddComponent(entity, "cerberus", fmt::format("{}{}", elv::fileSystem::MODELS_PATH, "cerberus/cerberus.fbx")); + auto& cerberusMesh = scene.AddComponent(entity, "cerberus", fmt::format("{}{}", elv::fileSystem::MODELS_PATH, "cerberus/cerberus.fbx")); + cerberusMesh.AddMaterialTexture(elv::Material::TextureSlot::Specular, "Cerberus_M.tga", fmt::format("{}{}", elv::fileSystem::MODELS_PATH, "cerberus/Textures")); const auto sponza = scene.CreateEntity(); m_models.emplace_back(sponza); scene.AddComponent(sponza, lia::vec3(0.0f), lia::vec3(0.01f)); scene.AddComponent(sponza, "sponza", fmt::format("{}{}", elv::fileSystem::MODELS_PATH, "sponza/sponza.obj")); - /* const auto tank = scene.CreateEntity(); - m_models.emplace_back(tank); - scene.AddComponent(tank, lia::vec3(10.0f, 0.0f, 0.0f), lia::vec3(1.0f)); - scene.AddComponent(tank, "tank", fmt::format("{}{}", elv::fileSystem::MODELS_PATH, "tank/tank.fbx")); + // const auto tank = scene.CreateEntity(); + // m_models.emplace_back(tank); + // scene.AddComponent(tank, lia::vec3(10.0f, 0.0f, 0.0f), lia::vec3(1.0f)); + // scene.AddComponent(tank, "tank", fmt::format("{}{}", elv::fileSystem::MODELS_PATH, "tank/tank.fbx")); - const auto robot = scene.CreateEntity(); - m_models.emplace_back(robot); - scene.AddComponent(robot, lia::vec3(20.0f, 0.0f, 0.0f), lia::vec3(1.0f)); - scene.AddComponent(robot, "robot", fmt::format("{}{}", elv::fileSystem::MODELS_PATH, "robot/robot.obj"));*/ + // const auto robot = scene.CreateEntity(); + // m_models.emplace_back(robot); + // scene.AddComponent(robot, lia::vec3(20.0f, 0.0f, 0.0f), lia::vec3(1.0f)); + // scene.AddComponent(robot, "robot", fmt::format("{}{}", elv::fileSystem::MODELS_PATH, "robot/robot.obj")); + + SetupCubes(); } void MeshModelSandbox::OnUpdate(float dt) @@ -78,7 +64,7 @@ void MeshModelSandbox::OnUpdate(float dt) void MeshModelSandbox::OnRender(float dt) { - elv::PROFILE("APP renderer: "); + // elv::PROFILE("APP renderer: "); elv::RenderCommand::SetClearColor(m_clearColor); elv::RenderCommand::Clear(); @@ -89,10 +75,6 @@ void MeshModelSandbox::OnRender(float dt) m_shader->SetVector3f("u_ViewPos", camera.GetPosition()); - // cube material - m_shader->SetInteger("u_Material.enableEmission", 0); - m_shader->SetFloat("u_Material.shininess", m_cubeShininess); - // directional light m_shader->SetInteger("u_DirLightEnabled", m_DirLightEnabled); if (m_DirLightEnabled) { @@ -148,10 +130,9 @@ void MeshModelSandbox::OnRender(float dt) // render models for (const auto modelEntity : m_models) { const auto& transform = scene.GetComponent(modelEntity); - m_shader->SetMatrix4("u_InversedNormalModel", lia::inverse(transform.worldMatrix)); - const auto& staticMesh = scene.GetComponent(modelEntity); + m_shader->SetMatrix4("u_InversedNormalModel", lia::inverse(transform.worldMatrix)); const auto& meshPtr = staticMesh.GetMeshPtr(); if (meshPtr) { elv::Renderer::Submit(m_shader, staticMesh.GetMeshPtr(), transform.worldMatrix); @@ -293,16 +274,6 @@ void MeshModelSandbox::OnImguiRender() } #endif -void MeshModelSandbox::OnTextureLoaded(const elv::events::TextureLoadedEvent& e) -{ - ++m_texturesLoaded; - - if (m_texturesToLoad == m_texturesLoaded) { - m_texturesIsReady = true; - SetupCubeMesh(); - } -} - void MeshModelSandbox::SetEnvironment(const int envIndex) { const auto& env = kEnvironmenMaterials[envIndex]; @@ -320,11 +291,8 @@ void MeshModelSandbox::SetEnvironment(const int envIndex) } } -void MeshModelSandbox::SetupCubeMesh() +void MeshModelSandbox::SetupCubes() { - auto diffuse = elv::textures::Get("wooden_container"); - auto specular = elv::textures::Get("wooden_container_specular"); - auto& scene = elv::GetScene(); auto mainCube = scene.CreateEntity(); @@ -334,9 +302,8 @@ void MeshModelSandbox::SetupCubeMesh() transform.pos = lia::vec3(0.0f, 0.5f, 0.0f); auto& mesh = scene.AddComponent(mainCube, "cube"); - auto& material = mesh.GetMeshPtr()->GetMaterial(); - material.SetTexture(elv::Material::TextureSlot::Diffuse, "texture_diffuse", diffuse); - material.SetTexture(elv::Material::TextureSlot::Specular, "texture_specular", specular); + mesh.AddMaterialTexture(elv::Material::TextureSlot::Diffuse, "wooden_container.png", "assets/images/"); + mesh.AddMaterialTexture(elv::Material::TextureSlot::Specular, "wooden_container_specular.png", "assets/images/"); for (size_t i = 0; i < kCubesAmount; ++i) { @@ -346,7 +313,7 @@ void MeshModelSandbox::SetupCubeMesh() auto& transform = scene.AddComponent(cube, kCubePositions[i], lia::vec3(0.5f)); auto& childMesh = scene.AddComponent(cube, "cube"); auto& childMaterial = childMesh.GetMeshPtr()->GetMaterial(); - childMaterial.SetTexture(elv::Material::TextureSlot::Diffuse, "texture_diffuse", diffuse); - childMaterial.SetTexture(elv::Material::TextureSlot::Specular, "texture_specular", specular); + childMesh.AddMaterialTexture(elv::Material::TextureSlot::Diffuse, "wooden_container.png", "assets/images/"); + childMesh.AddMaterialTexture(elv::Material::TextureSlot::Specular, "wooden_container_specular.png", "assets/images/"); } } diff --git a/Sandbox3D/src/MeshModelSandbox.h b/Sandbox3D/src/MeshModelSandbox.h index 59556ca..16bd0bd 100644 --- a/Sandbox3D/src/MeshModelSandbox.h +++ b/Sandbox3D/src/MeshModelSandbox.h @@ -4,11 +4,6 @@ #include "Helpers/EnvironmentSettings.h" -// forward declarations -namespace elv::events { -class TextureLoadedEvent; -} - class MeshModelSandbox : public elv::Application { public: MeshModelSandbox(); @@ -21,24 +16,17 @@ class MeshModelSandbox : public elv::Application { #endif private: - void OnTextureLoaded(const elv::events::TextureLoadedEvent& e); - void SetEnvironment(const int envIndex); - void SetupCubeMesh(); + void SetupCubes(); private: elv::EditorCameraController m_cameraController; - elv::events::EventHandler m_textureLoadedCallback; elv::Timer m_timer; lia::vec4 m_clearColor { 0.2f, 0.2f, 0.2f, 1.0f }; - int m_texturesToLoad { 3 }; - int m_texturesLoaded { 0 }; - bool m_texturesIsReady { false }; - bool m_DirLightEnabled { true }; bool m_PointLightEnabled { false }; bool m_SpotLightEnabled { false };