Started On Asset Manager
This commit is contained in:
parent
f298c48564
commit
6225c07dbd
@ -105,6 +105,12 @@ add_library(Core STATIC
|
|||||||
src/core/systems/MACROS.h
|
src/core/systems/MACROS.h
|
||||||
src/core/renderer/Renderer.cpp
|
src/core/renderer/Renderer.cpp
|
||||||
src/core/renderer/Renderer.h
|
src/core/renderer/Renderer.h
|
||||||
|
src/core/systems/AssetManager.cpp
|
||||||
|
src/core/systems/AssetManager.h
|
||||||
|
src/core/systems/Asset.cpp
|
||||||
|
src/core/systems/Asset.h
|
||||||
|
src/core/systems/assets/Texture2D.cpp
|
||||||
|
src/core/systems/assets/Texture2D.h
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(Core PUBLIC src/core)
|
target_include_directories(Core PUBLIC src/core)
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "Core.h"
|
#include "Core.h"
|
||||||
|
|
||||||
#include "systems/MACROS.h"
|
#include "systems/MACROS.h"
|
||||||
|
#include "systems/AssetManager.h"
|
||||||
|
|
||||||
namespace OX
|
namespace OX
|
||||||
{
|
{
|
||||||
@ -43,6 +44,8 @@ namespace OX
|
|||||||
window.SetWindowTitle(fullTitle);
|
window.SetWindowTitle(fullTitle);
|
||||||
|
|
||||||
Logger::LogOk("Core Initialization Complete.");
|
Logger::LogOk("Core Initialization Complete.");
|
||||||
|
|
||||||
|
AssetManager::Init("C:/Users/spenc/OneDrive/Desktop/OnyxProject");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -67,6 +70,7 @@ namespace OX
|
|||||||
void Core::Update()
|
void Core::Update()
|
||||||
{
|
{
|
||||||
OX_PROFILE_FUNCTION();
|
OX_PROFILE_FUNCTION();
|
||||||
|
AssetManager::Tick();
|
||||||
for (auto &layer: m_layers) {
|
for (auto &layer: m_layers) {
|
||||||
layer->Update(*this);
|
layer->Update(*this);
|
||||||
}
|
}
|
||||||
@ -93,6 +97,7 @@ namespace OX
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_layers.clear();
|
m_layers.clear();
|
||||||
|
AssetManager::Shutdown();
|
||||||
|
|
||||||
window.Shutdown();
|
window.Shutdown();
|
||||||
|
|
||||||
|
@ -5,4 +5,5 @@
|
|||||||
#include "Renderer.h"
|
#include "Renderer.h"
|
||||||
|
|
||||||
namespace OX {
|
namespace OX {
|
||||||
|
|
||||||
} // OX
|
} // OX
|
8
src/core/systems/Asset.cpp
Normal file
8
src/core/systems/Asset.cpp
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
//
|
||||||
|
// Created by spenc on 5/21/2025.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "Asset.h"
|
||||||
|
|
||||||
|
namespace OX {
|
||||||
|
} // OX
|
20
src/core/systems/Asset.h
Normal file
20
src/core/systems/Asset.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
//
|
||||||
|
// Created by spenc on 5/21/2025.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef ASSET_H
|
||||||
|
#define ASSET_H
|
||||||
|
#include "Logger.h"
|
||||||
|
|
||||||
|
namespace OX {
|
||||||
|
|
||||||
|
class Asset {
|
||||||
|
public:
|
||||||
|
virtual ~Asset() = default;
|
||||||
|
virtual std::string GetTypeName() const = 0;
|
||||||
|
virtual bool LoadFromFile(const std::string& path) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // OX
|
||||||
|
|
||||||
|
#endif //ASSET_H
|
110
src/core/systems/AssetManager.cpp
Normal file
110
src/core/systems/AssetManager.cpp
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
#include "AssetManager.h"
|
||||||
|
#include <yaml-cpp/yaml.h>
|
||||||
|
#include "assets/Texture2D.h"
|
||||||
|
#include "Logger.h"
|
||||||
|
#include "Profiler.h"
|
||||||
|
|
||||||
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
|
namespace OX {
|
||||||
|
|
||||||
|
std::unordered_map<std::string, std::shared_ptr<Asset>> AssetManager::s_AssetMap;
|
||||||
|
std::unordered_map<std::string, std::type_index> AssetManager::s_AssetTypes;
|
||||||
|
std::unordered_map<std::string, AssetManager::AssetMetadata> AssetManager::s_AssetDatabase;
|
||||||
|
|
||||||
|
std::mutex AssetManager::s_QueueMutex;
|
||||||
|
std::queue<std::pair<std::string, AssetManager::AssetMetadata>> AssetManager::s_LoadQueue;
|
||||||
|
|
||||||
|
std::thread AssetManager::s_BackgroundThread;
|
||||||
|
std::atomic<bool> AssetManager::s_Running = false;
|
||||||
|
|
||||||
|
fs::path AssetManager::s_ProjectDirectory;
|
||||||
|
|
||||||
|
void AssetManager::Init(const std::string& projectDir) {
|
||||||
|
OX_PROFILE_FUNCTION();
|
||||||
|
s_ProjectDirectory = fs::absolute(projectDir);
|
||||||
|
s_Running = true;
|
||||||
|
s_BackgroundThread = std::thread([] {
|
||||||
|
ScanAssetsRecursive(s_ProjectDirectory);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetManager::Shutdown() {
|
||||||
|
OX_PROFILE_FUNCTION();
|
||||||
|
s_Running = false;
|
||||||
|
if (s_BackgroundThread.joinable())
|
||||||
|
s_BackgroundThread.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetManager::ScanAssetsRecursive(const fs::path& root) {
|
||||||
|
OX_PROFILE_FUNCTION();
|
||||||
|
for (auto& entry : fs::recursive_directory_iterator(root)) {
|
||||||
|
if (!entry.is_regular_file()) continue;
|
||||||
|
|
||||||
|
const auto& path = entry.path();
|
||||||
|
std::string virtualPath = GetVirtualPath(path);
|
||||||
|
std::string type = DetectTypeFromExtension(path);
|
||||||
|
if (type.empty()) continue;
|
||||||
|
|
||||||
|
AssetMetadata meta{ type, path.string() };
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> lock(s_QueueMutex);
|
||||||
|
s_LoadQueue.push({ virtualPath, meta });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetManager::Tick() {
|
||||||
|
OX_PROFILE_FUNCTION();
|
||||||
|
std::lock_guard<std::mutex> lock(s_QueueMutex);
|
||||||
|
if (!s_LoadQueue.empty()) {
|
||||||
|
auto [id, meta] = s_LoadQueue.front();
|
||||||
|
s_LoadQueue.pop();
|
||||||
|
RegisterAssetMetadata(id, meta.type, meta.path);
|
||||||
|
LoadAsset(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string AssetManager::GetVirtualPath(const fs::path& absolute) {
|
||||||
|
OX_PROFILE_FUNCTION();
|
||||||
|
fs::path relative = fs::relative(absolute, s_ProjectDirectory);
|
||||||
|
return "res://" + relative.generic_string();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string AssetManager::DetectTypeFromExtension(const fs::path& path) {
|
||||||
|
OX_PROFILE_FUNCTION();
|
||||||
|
std::string ext = path.extension().string();
|
||||||
|
if (ext == ".png" || ext == ".jpg") return "texture2D";
|
||||||
|
if (ext == ".wav" || ext == ".ogg") return "audio";
|
||||||
|
if (ext == ".prefab" || ext == ".yaml") return "prefab";
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetManager::RegisterAssetMetadata(const std::string& id, const std::string& type, const std::string& path) {
|
||||||
|
OX_PROFILE_FUNCTION();
|
||||||
|
s_AssetDatabase[id] = { type, path };
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AssetManager::LoadAsset(const std::string& id) {
|
||||||
|
OX_PROFILE_FUNCTION();
|
||||||
|
auto it = s_AssetDatabase.find(id);
|
||||||
|
if (it == s_AssetDatabase.end()) return false;
|
||||||
|
|
||||||
|
const auto& meta = it->second;
|
||||||
|
std::shared_ptr<Asset> asset;
|
||||||
|
|
||||||
|
if (meta.type == "texture2D")
|
||||||
|
asset = std::make_shared<Texture2D>();
|
||||||
|
|
||||||
|
|
||||||
|
if (asset && asset->LoadFromFile(meta.path)) {
|
||||||
|
s_AssetMap[id] = asset;
|
||||||
|
s_AssetTypes.emplace(id, std::type_index(typeid(*asset)));
|
||||||
|
Logger::LogInfo("Loaded asset '%s' (%s)", id.c_str(), meta.path.c_str());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger::LogError("Failed to load asset '%s'", id.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace OX
|
60
src/core/systems/AssetManager.h
Normal file
60
src/core/systems/AssetManager.h
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
#include <typeindex>
|
||||||
|
#include <mutex>
|
||||||
|
#include <queue>
|
||||||
|
#include <filesystem>
|
||||||
|
#include <thread>
|
||||||
|
#include <atomic>
|
||||||
|
#include "Asset.h"
|
||||||
|
|
||||||
|
namespace OX {
|
||||||
|
|
||||||
|
class AssetManager {
|
||||||
|
public:
|
||||||
|
static void Init(const std::string& projectDir);
|
||||||
|
static void Shutdown();
|
||||||
|
static void Tick(); // Call once per frame
|
||||||
|
|
||||||
|
static void RegisterAssetMetadata(const std::string& id, const std::string& type, const std::string& path);
|
||||||
|
static bool LoadAsset(const std::string& id);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static std::shared_ptr<T> Get(const std::string& id) {
|
||||||
|
if (s_AssetMap.find(id) == s_AssetMap.end())
|
||||||
|
LoadAsset(id);
|
||||||
|
|
||||||
|
auto it = s_AssetMap.find(id);
|
||||||
|
if (it == s_AssetMap.end()) return nullptr;
|
||||||
|
if (s_AssetTypes[id] != std::type_index(typeid(T))) return nullptr;
|
||||||
|
|
||||||
|
return std::static_pointer_cast<T>(it->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct AssetMetadata {
|
||||||
|
std::string type;
|
||||||
|
std::string path;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void ScanAssetsRecursive(const std::filesystem::path& root);
|
||||||
|
static std::string DetectTypeFromExtension(const std::filesystem::path& path);
|
||||||
|
static std::string GetVirtualPath(const std::filesystem::path& absolute);
|
||||||
|
|
||||||
|
static std::unordered_map<std::string, std::shared_ptr<Asset>> s_AssetMap;
|
||||||
|
static std::unordered_map<std::string, std::type_index> s_AssetTypes;
|
||||||
|
static std::unordered_map<std::string, AssetMetadata> s_AssetDatabase;
|
||||||
|
|
||||||
|
static std::mutex s_QueueMutex;
|
||||||
|
static std::queue<std::pair<std::string, AssetMetadata>> s_LoadQueue;
|
||||||
|
|
||||||
|
static std::thread s_BackgroundThread;
|
||||||
|
static std::atomic<bool> s_Running;
|
||||||
|
|
||||||
|
static std::filesystem::path s_ProjectDirectory;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace OX
|
49
src/core/systems/assets/Texture2D.cpp
Normal file
49
src/core/systems/assets/Texture2D.cpp
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
//
|
||||||
|
// Created by spenc on 5/21/2025.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#include "Texture2D.h"
|
||||||
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
|
#include <stb/stb_image.h>
|
||||||
|
#include <GL/glew.h>
|
||||||
|
|
||||||
|
namespace OX
|
||||||
|
{
|
||||||
|
Texture2D::Texture2D() = default;
|
||||||
|
|
||||||
|
Texture2D::~Texture2D()
|
||||||
|
{
|
||||||
|
if (m_TextureID != 0) {
|
||||||
|
glDeleteTextures(1, &m_TextureID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Texture2D::LoadFromFile(const std::string &path)
|
||||||
|
{
|
||||||
|
stbi_set_flip_vertically_on_load(1);
|
||||||
|
int channels;
|
||||||
|
unsigned char *data = stbi_load(path.c_str(), &m_Width, &m_Height, &channels, 0);
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
Logger::LogError("Failed to load texture: %s", path.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLenum format = (channels == 4) ? GL_RGBA : GL_RGB;
|
||||||
|
|
||||||
|
glGenTextures(1, &m_TextureID);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, m_TextureID);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, format, m_Width, m_Height, 0, format, GL_UNSIGNED_BYTE, data);
|
||||||
|
glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
|
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
|
||||||
|
stbi_image_free(data);
|
||||||
|
Logger::LogVerbose("Loaded texture: %s (%dx%d)", path.c_str(), m_Width, m_Height);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} // namespace OX
|
33
src/core/systems/assets/Texture2D.h
Normal file
33
src/core/systems/assets/Texture2D.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
//
|
||||||
|
// Created by spenc on 5/21/2025.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "systems/Asset.h"
|
||||||
|
#include <string>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
|
||||||
|
namespace OX
|
||||||
|
{
|
||||||
|
class Texture2D : public Asset
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Texture2D();
|
||||||
|
|
||||||
|
~Texture2D();
|
||||||
|
|
||||||
|
bool LoadFromFile(const std::string &path) override;
|
||||||
|
|
||||||
|
std::string GetTypeName() const override { return "texture2D"; }
|
||||||
|
|
||||||
|
uint32_t GetID() const { return m_TextureID; }
|
||||||
|
int GetWidth() const { return m_Width; }
|
||||||
|
int GetHeight() const { return m_Height; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t m_TextureID = 0;
|
||||||
|
int m_Width = 0;
|
||||||
|
int m_Height = 0;
|
||||||
|
};
|
||||||
|
} // OX
|
@ -11,22 +11,22 @@
|
|||||||
#include "Windows/LoggerWindow.h"
|
#include "Windows/LoggerWindow.h"
|
||||||
#include "Windows/Viewport.h"
|
#include "Windows/Viewport.h"
|
||||||
|
|
||||||
namespace OX {
|
namespace OX
|
||||||
|
{
|
||||||
void Editor::Init(Core& core)
|
void Editor::Init(Core &core)
|
||||||
{
|
{
|
||||||
Logger::LogInfo("%s Init", m_name.c_str());
|
Logger::LogInfo("%s Init", m_name.c_str());
|
||||||
|
|
||||||
IMGUI_CHECKVERSION();
|
IMGUI_CHECKVERSION();
|
||||||
ImGui::CreateContext();
|
ImGui::CreateContext();
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO &io = ImGui::GetIO();
|
||||||
|
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
|
||||||
|
|
||||||
ImGui::StyleColorsDark();
|
ImGui::StyleColorsDark();
|
||||||
|
|
||||||
ImGuiStyle& style = ImGui::GetStyle();
|
ImGuiStyle &style = ImGui::GetStyle();
|
||||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) {
|
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) {
|
||||||
style.WindowRounding = 5.0f;
|
style.WindowRounding = 5.0f;
|
||||||
style.Colors[ImGuiCol_WindowBg].w = 1.0f;
|
style.Colors[ImGuiCol_WindowBg].w = 1.0f;
|
||||||
@ -38,15 +38,13 @@ namespace OX {
|
|||||||
primaryViewport = new Viewport(); // The first time ive ever use the new keywork...
|
primaryViewport = new Viewport(); // The first time ive ever use the new keywork...
|
||||||
}
|
}
|
||||||
|
|
||||||
void Editor::Update(Core& core)
|
void Editor::Update(Core &core)
|
||||||
{
|
{
|
||||||
OX_PROFILE_FUNCTION();
|
OX_PROFILE_FUNCTION();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Editor::Draw(Core& core)
|
void Editor::Draw(Core &core)
|
||||||
{
|
{
|
||||||
|
|
||||||
OX_PROFILE_FUNCTION();
|
OX_PROFILE_FUNCTION();
|
||||||
|
|
||||||
|
|
||||||
@ -55,18 +53,19 @@ namespace OX {
|
|||||||
ImGui::NewFrame();
|
ImGui::NewFrame();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// === Main Docking Space ===
|
// === Main Docking Space ===
|
||||||
ImGuiWindowFlags windowFlags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoBackground;
|
ImGuiWindowFlags windowFlags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking |
|
||||||
|
ImGuiWindowFlags_NoBackground;
|
||||||
|
|
||||||
const ImGuiViewport* viewport = ImGui::GetMainViewport();
|
const ImGuiViewport *viewport = ImGui::GetMainViewport();
|
||||||
ImGui::SetNextWindowPos(viewport->WorkPos);
|
ImGui::SetNextWindowPos(viewport->WorkPos);
|
||||||
ImGui::SetNextWindowSize(viewport->WorkSize);
|
ImGui::SetNextWindowSize(viewport->WorkSize);
|
||||||
ImGui::SetNextWindowViewport(viewport->ID);
|
ImGui::SetNextWindowViewport(viewport->ID);
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
|
||||||
windowFlags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove;
|
windowFlags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize |
|
||||||
|
ImGuiWindowFlags_NoMove;
|
||||||
windowFlags |= ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus;
|
windowFlags |= ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus;
|
||||||
|
|
||||||
ImGui::Begin("DockSpace Root", nullptr, windowFlags);
|
ImGui::Begin("DockSpace Root", nullptr, windowFlags);
|
||||||
@ -81,41 +80,65 @@ namespace OX {
|
|||||||
|
|
||||||
ImGui::Begin("Profiler");
|
ImGui::Begin("Profiler");
|
||||||
|
|
||||||
const auto& tree = Profiler::GetSavedTree();
|
const auto &tree = Profiler::GetSavedTree();
|
||||||
if (tree.empty()) {
|
if (tree.empty()) {
|
||||||
ImGui::Text("No samples yet.");
|
ImGui::Text("No samples yet.");
|
||||||
} else {
|
} else {
|
||||||
std::function<void(const Profiler::SavedSample&, int)> DrawNode;
|
if (ImGui::BeginTable("ProfilerTable", 3,
|
||||||
DrawNode = [&](const Profiler::SavedSample& node, int depth) {
|
ImGuiTableFlags_Resizable | ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersInnerV)) {
|
||||||
// Indentation
|
ImGui::TableSetupColumn("Section");
|
||||||
ImGui::Indent(depth * 10.0f);
|
ImGui::TableSetupColumn("Calls", ImGuiTableColumnFlags_WidthFixed, 60.0f);
|
||||||
|
ImGui::TableSetupColumn("Total Time (ms)", ImGuiTableColumnFlags_WidthFixed, 120.0f);
|
||||||
|
ImGui::TableHeadersRow();
|
||||||
|
|
||||||
// Color based on time
|
std::function<void(const Profiler::SavedSample &)> DrawNode;
|
||||||
ImVec4 color;
|
DrawNode = [&](const Profiler::SavedSample &node)
|
||||||
if (node.totalTime > 10.0f) color = ImVec4(1.0f, 0.2f, 0.2f, 1.0f); // red
|
{
|
||||||
else if (node.totalTime > 5.0f) color = ImVec4(1.0f, 0.5f, 0.0f, 1.0f); // orange
|
ImGui::TableNextRow();
|
||||||
else if (node.totalTime > 1.0f) color = ImVec4(1.0f, 1.0f, 0.0f, 1.0f); // yellow
|
|
||||||
else color = ImVec4(0.2f, 1.0f, 0.2f, 1.0f); // green
|
|
||||||
|
|
||||||
ImGui::PushStyleColor(ImGuiCol_Text, color);
|
// === Section name with Tree UI ===
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
|
||||||
ImGui::Text("%s (%d): %.2f ms", node.name.c_str(), node.callCount, node.totalTime);
|
// Color based on total time
|
||||||
|
ImVec4 color;
|
||||||
|
if (node.totalTime > 10.0f) color = ImVec4(1.0f, 0.2f, 0.2f, 1.0f); // red
|
||||||
|
else if (node.totalTime > 5.0f) color = ImVec4(1.0f, 0.5f, 0.0f, 1.0f); // orange
|
||||||
|
else if (node.totalTime > 1.0f) color = ImVec4(1.0f, 1.0f, 0.0f, 1.0f); // yellow
|
||||||
|
else color = ImVec4(0.4f, 1.0f, 0.4f, 1.0f); // green
|
||||||
|
|
||||||
ImGui::PopStyleColor();
|
ImGui::PushStyleColor(ImGuiCol_Text, color);
|
||||||
for (const auto& child : node.children) {
|
bool open = ImGui::TreeNodeEx(node.name.c_str(),
|
||||||
DrawNode(child, depth + 1);
|
ImGuiTreeNodeFlags_SpanAllColumns | ImGuiTreeNodeFlags_DefaultOpen);
|
||||||
|
ImGui::PopStyleColor();
|
||||||
|
|
||||||
|
// === Call count ===
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("%d", node.callCount);
|
||||||
|
|
||||||
|
// === Total time ===
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("%.2f", node.totalTime);
|
||||||
|
|
||||||
|
// === Recurse if open ===
|
||||||
|
if (open) {
|
||||||
|
for (const auto &child: node.children) {
|
||||||
|
DrawNode(child);
|
||||||
|
}
|
||||||
|
ImGui::TreePop();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const auto &root: tree) {
|
||||||
|
DrawNode(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::Unindent(depth * 10.0f);
|
ImGui::EndTable();
|
||||||
};
|
|
||||||
|
|
||||||
for (const auto& root : tree) {
|
|
||||||
DrawNode(root, 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
|
|
||||||
|
|
||||||
ImGui::End(); // DockSpace Root
|
ImGui::End(); // DockSpace Root
|
||||||
|
|
||||||
// --- Render ImGui onto FBO 0 ---
|
// --- Render ImGui onto FBO 0 ---
|
||||||
@ -127,12 +150,10 @@ namespace OX {
|
|||||||
ImGui::UpdatePlatformWindows();
|
ImGui::UpdatePlatformWindows();
|
||||||
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Editor::Shutdown(Core& core)
|
void Editor::Shutdown(Core &core)
|
||||||
{
|
{
|
||||||
|
|
||||||
delete primaryViewport;
|
delete primaryViewport;
|
||||||
primaryViewport = nullptr;
|
primaryViewport = nullptr;
|
||||||
|
|
||||||
@ -141,8 +162,5 @@ namespace OX {
|
|||||||
ImGui_ImplOpenGL3_Shutdown();
|
ImGui_ImplOpenGL3_Shutdown();
|
||||||
ImGui_ImplGlfw_Shutdown();
|
ImGui_ImplGlfw_Shutdown();
|
||||||
ImGui::DestroyContext();
|
ImGui::DestroyContext();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} // OX
|
||||||
} // OX
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#ifndef EDITOR_H
|
#ifndef EDITOR_H
|
||||||
#define EDITOR_H
|
#define EDITOR_H
|
||||||
#define OX_EDITOR_VERSION "Obsidian Editor (0.3.2)"
|
#define OX_EDITOR_VERSION "Obsidian Editor (0.1.5)"
|
||||||
#include "Layer.h"
|
#include "Layer.h"
|
||||||
#include "Core.h"
|
#include "Core.h"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user