Skip to content

Commit

Permalink
Improved editor logic
Browse files Browse the repository at this point in the history
- scene context menu: create entity
- entity context menu: create child, delete entity
- "add component" button for entity
- componet settings context menu
- material texture maps edit
  • Loading branch information
denyskryvytskyi committed Mar 24, 2024
1 parent eada685 commit 2f836fd
Show file tree
Hide file tree
Showing 16 changed files with 437 additions and 138 deletions.
292 changes: 247 additions & 45 deletions Engine/src/Editor/Panels/SceneHierarchyPanel.cpp

Large diffs are not rendered by default.

9 changes: 7 additions & 2 deletions Engine/src/Editor/Panels/SceneHierarchyPanel.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,18 @@ class SceneHierarchyPanel {
void OnImGuiRender();

private:
void DrawEntity(const ecs::Entity parentEntity, Scene& scene);
void DrawProperties(Scene& scene);
void DrawEntity(const ecs::Entity parentEntity);
void DrawProperties();

template<typename T>
void DisplayAddComponentEntry(const std::string& name);

private:
ecs::Entity m_selectedEntity { ecs::INVALID_ENTITY_ID };
int m_entityNameCounter { 0 };

Scene* m_context { nullptr };

SharedPtr<ecs::ComponentPool<SceneNodeComponent>> m_nodesPool { nullptr };
SharedPtr<ecs::ComponentPool<TagComponent>> m_tagsPool { nullptr };
};
Expand Down
2 changes: 2 additions & 0 deletions Engine/src/Renderer/Material.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ class Material {
const lia::vec3& GetEmissionColor() const { return m_emissiveColor; }
float GetShininess() const { return m_shininess; }

const std::string& GetTextureName(TextureSlot slot) const { return m_textures[slot].name; }

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

private:
Expand Down
2 changes: 1 addition & 1 deletion Engine/src/Renderer/Mesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ void Mesh::AddSubmesh(Mesh&& submesh)
m_submeshes.emplace_back(std::move(submesh));
}

void Mesh::AddMaterialTexture(const Material::TextureSlot slot, const std::string& name, const std::string& path, bool async)
void Mesh::SetMaterialTexture(const Material::TextureSlot slot, const std::string& name, const std::string& path, bool async)
{
m_material.SetTexture(slot, name, path, async);
}
Expand Down
4 changes: 3 additions & 1 deletion Engine/src/Renderer/Mesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,16 @@ class Mesh {
void SetInfo(const std::vector<MeshVertex>& vertices, const std::vector<std::uint32_t>& indices, const std::vector<MeshTexture>& texturesInfo);
void Draw(const SharedPtr<Shader>& shader) const;
void AddSubmesh(Mesh&& submesh);
void AddMaterialTexture(const Material::TextureSlot slot, const std::string& name, const std::string& path, bool async);
void SetMaterialTexture(const Material::TextureSlot slot, const std::string& name, const std::string& path, bool async);

void LoadTextures(const std::string& dir, const bool async);

void SetTopology(const RenderTopology topology) { m_topology = topology; }

Material& GetMaterial() { return m_material; }

RenderTopology GetRenderTopology() const { return m_topology; }

private:
void SetupMesh();
void SetupMaterial(const std::vector<MeshTexture>& texturesInfo);
Expand Down
2 changes: 1 addition & 1 deletion Engine/src/Resources/FontManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ void FontManager::Load(const std::string& fontName, const std::string& fontPath)
if (c != 32) {

const std::string textureName = fmt::format("{}{}{}", fontName, "text2d_glyph_", c);
texture = textures::Load(textureName, face->glyph->bitmap.width, face->glyph->bitmap.rows, 1);
texture = textures::LoadUnique(textureName, face->glyph->bitmap.width, face->glyph->bitmap.rows, 1);
texture->SetWrappingMode(TextureWrappingMode::ClampToBorder);
texture->SetData(face->glyph->bitmap.buffer);
}
Expand Down
11 changes: 11 additions & 0 deletions Engine/src/Resources/MeshLibrary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,17 @@ SharedPtr<Mesh> MeshLibrary::GetMesh(const std::string& name) const
return it != m_meshes.end() ? it->second : nullptr;
}

std::vector<std::string> MeshLibrary::GetMeshes() const
{
std::vector<std::string> names;

for (const auto& mesh : m_meshes) {
names.emplace_back(mesh.first);
}

return names;
}

void MeshLibrary::ProcessMeshInfo(const LoadedMeshesInfo& meshesInfo)
{
// process mesh and submeshes
Expand Down
3 changes: 3 additions & 0 deletions Engine/src/Resources/MeshLibrary.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ class MeshLibrary {

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

// return list of names of all meshes
std::vector<std::string> GetMeshes() const;

private:
void ProcessMeshInfo(const LoadedMeshesInfo& meshInfo);
void LoadPrimitives();
Expand Down
17 changes: 15 additions & 2 deletions Engine/src/Resources/TextureManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ void TextureManager::Load(const std::string& textureName, const std::string& fil
EL_CORE_INFO("Texture {0} is already loaded.", textureName);
}

SharedPtr<Texture2D> TextureManager::Load(const std::string& textureName, std::uint32_t width, std::uint32_t height, uint32_t nrChannels)
SharedPtr<Texture2D> TextureManager::Load(const std::string& textureName, std::uint32_t width, std::uint32_t height, uint32_t nrChannels, bool addToPool)
{
// check whether we already loaded this texture
auto it = m_textures.find(textureName);
Expand All @@ -71,7 +71,9 @@ SharedPtr<Texture2D> TextureManager::Load(const std::string& textureName, std::u
switch (Renderer::GetAPI()) {
case RendererAPI::API::OpenGL: {
SharedPtr<Texture2D> texture = MakeSharedPtr<OpenGLTexture2D>(width, height, nrChannels);
m_textures.insert({ textureName, texture });
if (addToPool) {
m_textures.insert({ textureName, texture });
}
return texture;
}
default:
Expand Down Expand Up @@ -134,6 +136,17 @@ SharedPtr<Texture2D> TextureManager::Get(std::string_view textureName)
return it != m_textures.end() ? it->second : nullptr;
}

std::vector<std::string> TextureManager::GetTextureNames() const
{
std::vector<std::string> names;

for (const auto texture : m_textures) {
names.emplace_back(texture.first);
}

return names;
}

void TextureManager::CreateTexture(const LoadedTextureInfo& info)
{
switch (Renderer::GetAPI()) {
Expand Down
9 changes: 8 additions & 1 deletion Engine/src/Resources/TextureManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,16 @@ class TextureManager {
void Load(const std::string& textureName, const std::string& filePath, const bool isAsync);

// just create texture for specific texture implementation
SharedPtr<Texture2D> Load(const std::string& textureName, std::uint32_t width, std::uint32_t height, uint32_t nrChannels);
SharedPtr<Texture2D> Load(const std::string& textureName, std::uint32_t width, std::uint32_t height, uint32_t nrChannels, bool AddToPool = true);

void Init();
void Update();
void Shutdown();

SharedPtr<Texture2D> Get(std::string_view textureName);

std::vector<std::string> GetTextureNames() const;

private:
void CreateTexture(const LoadedTextureInfo& info);

Expand All @@ -58,6 +60,11 @@ inline SharedPtr<Texture2D> Load(const std::string& textureName, std::uint32_t w
return gTextureManager.Load(textureName, width, height, nrChannels);
}

inline SharedPtr<Texture2D> LoadUnique(const std::string& textureName, std::uint32_t width, std::uint32_t height, uint32_t nrChannels = 3)
{
return gTextureManager.Load(textureName, width, height, nrChannels, false);
}

inline SharedPtr<Texture2D> Get(std::string_view textureName)
{
return gTextureManager.Get(textureName);
Expand Down
47 changes: 40 additions & 7 deletions Engine/src/Scene/Components/StaticMeshComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ void StaticMeshComponent::LoadMesh(const RenderTopology topology)
if (!m_meshName.empty()) {
auto meshPtr = gMeshLibrary.GetMesh(m_meshName);
if (meshPtr) {
m_meshPtr = meshPtr;
// make new instance of cube mesh to be able to change material only for this entity
m_meshPtr = MakeSharedPtr<Mesh>(*meshPtr);
m_meshPtr->SetTopology(topology);
} else if (m_meshPath.empty()) {
EL_CORE_WARN("Failed to set mesh to the Static Mesh Component, mesh path is empty");
Expand All @@ -32,7 +33,6 @@ void StaticMeshComponent::LoadMesh(const RenderTopology topology)
// load textures async
const std::string directory = m_meshPath.substr(0, m_meshPath.find_last_of('/'));
if (m_meshPtr) {
m_meshPtr->SetTopology(topology);
m_meshPtr->LoadTextures(directory, true);
}
}
Expand All @@ -42,15 +42,48 @@ void StaticMeshComponent::LoadMesh(const RenderTopology topology)
}
}

Material& StaticMeshComponent::GetMaterial()
void StaticMeshComponent::ResetMesh(const std::string& newMeshName, const RenderTopology topology)
{
EL_ASSERT(m_meshPtr, "Failed to get material: mesh is empty");
if (!newMeshName.empty()) {
auto meshPtr = gMeshLibrary.GetMesh(newMeshName);
if (meshPtr) {
m_meshPtr = MakeSharedPtr<Mesh>(*meshPtr);
m_meshPtr->SetTopology(topology);
} else {
EL_CORE_WARN("Failed to reset mesh: mesh {} isn't imported", newMeshName.c_str());
}
}
}

void StaticMeshComponent::SetTopology(const RenderTopology topology)
{
if (m_meshPtr) {
m_meshPtr->SetTopology(topology);
}
}

Material* StaticMeshComponent::GetMaterial()
{
if (m_meshPtr) {
return &m_meshPtr->GetMaterial();
}

EL_CORE_ERROR("Failed to get material: mesh is empty");

return nullptr;
}

RenderTopology StaticMeshComponent::GetRenderTopology() const
{
if (m_meshPtr) {
return m_meshPtr->GetRenderTopology();
}

return m_meshPtr->GetMaterial();
return RenderTopology::Triangles;
}

void StaticMeshComponent::AddMaterialTexture(const Material::TextureSlot slot, const std::string& name, const std::string& path, bool async)
void StaticMeshComponent::SetMaterialTexture(const Material::TextureSlot slot, const std::string& name, const std::string& path, bool async)
{
m_meshPtr->AddMaterialTexture(slot, name, path, async);
m_meshPtr->SetMaterialTexture(slot, name, path, async);
}
} // namespace elv
12 changes: 9 additions & 3 deletions Engine/src/Scene/Components/StaticMeshComponent.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,16 @@ class StaticMeshComponent {
LoadMesh(topology);
}

const SharedPtr<Mesh>& GetMeshPtr() const { return m_meshPtr; }
Material& GetMaterial();
void ResetMesh(const std::string& newMeshName, const RenderTopology topology = RenderTopology::Triangles);
void SetMaterialTexture(const Material::TextureSlot slot, const std::string& name, const std::string& path, bool async = true);
void SetTopology(const RenderTopology topology);
void SetName(const std::string& name) { m_meshName = name; }

void AddMaterialTexture(const Material::TextureSlot slot, const std::string& name, const std::string& path, bool async = true);
const SharedPtr<Mesh>& GetMeshPtr() const { return m_meshPtr; }
const std::string& GetMeshName() const { return m_meshName; }
const std::string& GetMeshPath() const { return m_meshPath; }
Material* GetMaterial();
RenderTopology GetRenderTopology() const;

private:
void LoadMesh(const RenderTopology topology);
Expand Down
17 changes: 11 additions & 6 deletions Engine/src/Scene/Systems/Render2dSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,12 @@ void Render2dSystem::OnRender(float dt)
for (uint32_t index = 0; index < spriteComponents.size(); ++index) {
const ecs::Entity entity = m_spritesPool->GetEntity(index);

auto& spriteComponent = spriteComponents[index];
auto& transformComponent = m_trasformsPool->GetComponent(entity);
if (spriteComponent.texture != nullptr) {
Renderer2D::DrawQuad(spriteComponent.texture, transformComponent.pos, transformComponent.scale, transformComponent.rotation.z, spriteComponent.color);
if (m_pScene->HasComponent<TransformComponent>(entity)) {
auto& spriteComponent = spriteComponents[index];
auto& transformComponent = m_trasformsPool->GetComponent(entity);
if (spriteComponent.texture != nullptr) {
Renderer2D::DrawQuad(spriteComponent.texture, transformComponent.pos, transformComponent.scale, transformComponent.rotation.z, spriteComponent.color);
}
}
}
}
Expand Down Expand Up @@ -94,8 +96,11 @@ void Render2dSystem::OnRender(float dt)

auto& textComponent = textComponents[i];
if (textComponent.isVisible) {
auto& rectTransform = m_rectTransformPool->GetComponent(entity);
TextRenderer::RenderText(textComponent.text, textComponent.fontName, rectTransform.pos, rectTransform.scale, textComponent.color);

if (m_pScene->HasComponent<RectTransformComponent>(entity)) {
auto& rectTransform = m_rectTransformPool->GetComponent(entity);
TextRenderer::RenderText(textComponent.text, textComponent.fontName, rectTransform.pos, rectTransform.scale, textComponent.color);
}
}
}

Expand Down
74 changes: 41 additions & 33 deletions Engine/src/Scene/Systems/RenderSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,16 +62,18 @@ void RenderSystem::OnRender(float dt)

isAnyPointLightActive = true;
const auto entity = pointLightsPool->GetEntity(i);
auto& transform = m_pScene->GetComponent<TransformComponent>(entity);

m_shader->SetVector3f(fmt::format("u_PointLights[{}].position", activePointLightsCounter), transform.pos);
m_shader->SetVector3f(fmt::format("u_PointLights[{}].ambient", activePointLightsCounter), pointLight.ambient);
m_shader->SetVector3f(fmt::format("u_PointLights[{}].diffuse", activePointLightsCounter), pointLight.diffuse);
m_shader->SetVector3f(fmt::format("u_PointLights[{}].specular", activePointLightsCounter), pointLight.specular);
m_shader->SetFloat(fmt::format("u_PointLights[{}].constant", activePointLightsCounter), pointLight.constant);
m_shader->SetFloat(fmt::format("u_PointLights[{}].linear", activePointLightsCounter), pointLight.linear);
m_shader->SetFloat(fmt::format("u_PointLights[{}].quadratic", activePointLightsCounter), pointLight.quadratic);
++activePointLightsCounter;
if (m_pScene->HasComponent<TransformComponent>(entity)) {
auto& transform = m_pScene->GetComponent<TransformComponent>(entity);

m_shader->SetVector3f(fmt::format("u_PointLights[{}].position", activePointLightsCounter), transform.pos);
m_shader->SetVector3f(fmt::format("u_PointLights[{}].ambient", activePointLightsCounter), pointLight.ambient);
m_shader->SetVector3f(fmt::format("u_PointLights[{}].diffuse", activePointLightsCounter), pointLight.diffuse);
m_shader->SetVector3f(fmt::format("u_PointLights[{}].specular", activePointLightsCounter), pointLight.specular);
m_shader->SetFloat(fmt::format("u_PointLights[{}].constant", activePointLightsCounter), pointLight.constant);
m_shader->SetFloat(fmt::format("u_PointLights[{}].linear", activePointLightsCounter), pointLight.linear);
m_shader->SetFloat(fmt::format("u_PointLights[{}].quadratic", activePointLightsCounter), pointLight.quadratic);
++activePointLightsCounter;
}
}
m_shader->SetInteger("u_PointLightEnabled", isAnyPointLightActive);
m_shader->SetInteger("u_ActivePointLightsAmount", activePointLightsCounter);
Expand All @@ -90,18 +92,20 @@ void RenderSystem::OnRender(float dt)
isAnySpotlightAvailable = true;

const auto entity = spotLightsPool->GetEntity(i);
auto& transform = m_pScene->GetComponent<TransformComponent>(entity);

m_shader->SetVector3f("u_SpotLight.position", transform.pos);
m_shader->SetVector3f("u_SpotLight.direction", transform.rotation);
m_shader->SetVector3f("u_SpotLight.ambient", spotlight.ambient);
m_shader->SetVector3f("u_SpotLight.diffuse", spotlight.diffuse);
m_shader->SetVector3f("u_SpotLight.specular", spotlight.specular);
m_shader->SetFloat("u_SpotLight.cutOff", cos(lia::radians(spotlight.cutOff)));
m_shader->SetFloat("u_SpotLight.outerCutOff", cos(lia::radians(spotlight.outerCutOff)));
m_shader->SetFloat("u_SpotLight.constant", spotlight.constant);
m_shader->SetFloat("u_SpotLight.linear", spotlight.linear);
m_shader->SetFloat("u_SpotLight.quadratic", spotlight.quadratic);
if (m_pScene->HasComponent<TransformComponent>(entity)) {
auto& transform = m_pScene->GetComponent<TransformComponent>(entity);

m_shader->SetVector3f("u_SpotLight.position", transform.pos);
m_shader->SetVector3f("u_SpotLight.direction", transform.rotation);
m_shader->SetVector3f("u_SpotLight.ambient", spotlight.ambient);
m_shader->SetVector3f("u_SpotLight.diffuse", spotlight.diffuse);
m_shader->SetVector3f("u_SpotLight.specular", spotlight.specular);
m_shader->SetFloat("u_SpotLight.cutOff", cos(lia::radians(spotlight.cutOff)));
m_shader->SetFloat("u_SpotLight.outerCutOff", cos(lia::radians(spotlight.outerCutOff)));
m_shader->SetFloat("u_SpotLight.constant", spotlight.constant);
m_shader->SetFloat("u_SpotLight.linear", spotlight.linear);
m_shader->SetFloat("u_SpotLight.quadratic", spotlight.quadratic);
}
}
m_shader->SetInteger("u_SpotLightEnabled", isAnySpotlightAvailable);

Expand All @@ -115,14 +119,16 @@ void RenderSystem::OnRender(float dt)
for (std::uint32_t i = 0; i < meshPool->Size(); ++i) {
auto entity = meshPool->GetEntity(i);

auto& meshComponent = meshComponents[i];
auto& transform = m_pScene->GetComponent<TransformComponent>(entity);
if (m_pScene->HasComponent<TransformComponent>(entity)) {
auto& meshComponent = meshComponents[i];
auto& transform = m_pScene->GetComponent<TransformComponent>(entity);

// TODO: maybe cache inverse world matrix too
m_shader->SetMatrix4("u_InversedNormalModel", lia::inverse(transform.worldMatrix));
const auto& meshPtr = meshComponent.GetMeshPtr();
if (meshPtr) {
Renderer::Submit(m_shader, meshPtr, transform.worldMatrix);
// TODO: maybe cache inverse world matrix too
m_shader->SetMatrix4("u_InversedNormalModel", lia::inverse(transform.worldMatrix));
const auto& meshPtr = meshComponent.GetMeshPtr();
if (meshPtr) {
Renderer::Submit(m_shader, meshPtr, transform.worldMatrix);
}
}
}

Expand All @@ -139,12 +145,14 @@ void RenderSystem::OnRender(float dt)
}

const auto entity = pointLightsPool->GetEntity(i);
auto& transform = m_pScene->GetComponent<TransformComponent>(entity);
if (m_pScene->HasComponent<TransformComponent>(entity)) {
auto& transform = m_pScene->GetComponent<TransformComponent>(entity);

m_lightShader->SetVector3f("u_Color.ambient", pointLight.ambient);
m_lightShader->SetVector3f("u_Color.diffuse", pointLight.diffuse);
m_lightShader->SetVector3f("u_Color.ambient", pointLight.ambient);
m_lightShader->SetVector3f("u_Color.diffuse", pointLight.diffuse);

Renderer::Submit(m_lightShader, m_debugLightMesh, transform.worldMatrix);
Renderer::Submit(m_lightShader, m_debugLightMesh, transform.worldMatrix);
}
}
}

Expand Down
Loading

0 comments on commit 2f836fd

Please sign in to comment.