Skip to content

Commit

Permalink
Improved material system
Browse files Browse the repository at this point in the history
  • Loading branch information
denyskryvytskyi committed Mar 17, 2024
1 parent e64c259 commit ac0e770
Show file tree
Hide file tree
Showing 21 changed files with 115 additions and 108 deletions.
File renamed without changes
Binary file added .github/demo/models_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
31 changes: 19 additions & 12 deletions Engine/src/Renderer/Material.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<Texture2D>& texture)
void Material::SetTexture(const TextureSlot slot, const std::string& name, SharedPtr<Texture2D> texture)
{
auto& map = m_textures[slot];
map.name = name;
Expand All @@ -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) {
Expand Down Expand Up @@ -83,17 +101,6 @@ void Material::ApplyMaterial(const SharedPtr<Shader>& 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);
Expand Down
30 changes: 27 additions & 3 deletions Engine/src/Renderer/Material.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,34 @@ class Material {
};

public:
void SetTexture(const TextureSlot slot, const std::string& name, const SharedPtr<Texture2D>& 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<Texture2D> 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);
Expand All @@ -41,7 +66,6 @@ class Material {
float GetShininess() const { return m_shininess; }

void ApplyMaterial(const SharedPtr<Shader>& shader) const;
void ResetMaterial() const;

private:
void LoadTexture(const std::string& dir, const bool async, TextureMap& map, TextureSlot slot);
Expand All @@ -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
20 changes: 14 additions & 6 deletions Engine/src/Renderer/Mesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,25 +30,33 @@ Mesh::Mesh(const std::vector<MeshVertex>& vertices, const std::vector<std::uint3
SetupMaterial(texturesInfo);
}

void Mesh::LoadTextures(const std::string& dir, const bool async)
void Mesh::SetInfo(const std::vector<MeshVertex>& vertices, const std::vector<std::uint32_t>& indices, const std::vector<MeshTexture>& 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)
{
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>& 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) {
Expand Down
6 changes: 3 additions & 3 deletions Engine/src/Renderer/Mesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,16 @@ class Mesh {

virtual ~Mesh() = default;

void SetInfo(const std::vector<MeshVertex>& vertices, const std::vector<std::uint32_t>& indices, const std::vector<MeshTexture>& texturesInfo);
void Draw(const SharedPtr<elv::Shader>& 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<MeshTexture>& texturesInfo);
Expand Down
19 changes: 10 additions & 9 deletions Engine/src/Resources/MeshLibrary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ constexpr float PI = 3.14159265359f;
constexpr float TAU = 6.28318530717f;
//

static void LoadMeshFromFile(std::vector<LoadedMeshesInfo>& loadedMeshesInfo, const std::string& meshName, const std::string& meshPath)
static void LoadMeshFromFile(std::vector<LoadedMeshesInfo>& loadedMeshesInfo, const std::string& meshName, const std::string& meshPath, SharedPtr<Mesh> root)
{
LoadedMeshesInfo info;
info.name = meshName;
info.texturesDir = meshPath;
info.root = root;

ImportModel(meshPath, info);

Expand Down Expand Up @@ -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<Mesh> root)
{
// check whether we already loaded this mesh
auto it = m_meshes.find(name);
Expand All @@ -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;
}
Expand All @@ -86,13 +86,14 @@ SharedPtr<Mesh> MeshLibrary::GetMesh(const std::string& name) const
void MeshLibrary::ProcessMeshInfo(const LoadedMeshesInfo& meshesInfo)
{
// process mesh and submeshes
SharedPtr<Mesh> 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<Mesh>(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));
Expand Down
2 changes: 1 addition & 1 deletion Engine/src/Resources/MeshLibrary.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<Mesh> root);

SharedPtr<Mesh> GetMesh(const std::string& name) const;

Expand Down
5 changes: 3 additions & 2 deletions Engine/src/Resources/ModelImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
}
}
Expand Down
3 changes: 1 addition & 2 deletions Engine/src/Resources/ModelImporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ struct LoadedMeshInfo {

struct LoadedMeshesInfo {
std::string name;
std::string texturesDir;

SharedPtr<Mesh> root;
std::vector<LoadedMeshInfo> meshes;
};

Expand Down
13 changes: 11 additions & 2 deletions Engine/src/Scene/Components/StaticMeshComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#include "Events/MeshEvent.h"

namespace elv {
#pragma optimize("", off)
void StaticMeshComponent::LoadMesh(const RenderTopology topology)
{
if (!m_meshName.empty()) {
Expand All @@ -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<Mesh>();
m_meshPtr->SetTopology(topology);

gMeshLibrary.LoadMesh(m_meshName, m_meshPath, m_meshPtr);

events::Subscribe<events::MeshLoadedEvent>([&](const events::MeshLoadedEvent& e) {
if (e.meshName == m_meshName) {
m_meshPtr = gMeshLibrary.GetMesh(m_meshName);
Expand All @@ -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
3 changes: 3 additions & 0 deletions Engine/src/Scene/Components/StaticMeshComponent.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include "Renderer/Material.h"
#include "Renderer/RenderTopology.h"

namespace elv {
Expand Down Expand Up @@ -31,6 +32,8 @@ class StaticMeshComponent {

const SharedPtr<Mesh>& 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);

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Binary file removed Sandbox3D/assets/models/cerberus/Cerberus.tbscene
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading

0 comments on commit ac0e770

Please sign in to comment.