Set Up Base
This commit is contained in:
parent
5278c9fb43
commit
16a70b888d
@ -86,6 +86,7 @@ file(GLOB_RECURSE CORE_SOURCES CONFIGURE_DEPENDS
|
||||
|
||||
add_library(Core STATIC
|
||||
${CORE_SOURCES}
|
||||
src/core/systems/MACROS.h
|
||||
)
|
||||
|
||||
target_include_directories(Core PUBLIC src/core)
|
||||
@ -105,6 +106,8 @@ add_executable(Editor ${APP_SOURCES}
|
||||
main.cpp
|
||||
src/editor/Editor.cpp
|
||||
src/editor/Editor.h
|
||||
src/editor/Windows/LoggerWindow.cpp
|
||||
src/editor/Windows/LoggerWindow.h
|
||||
)
|
||||
|
||||
target_include_directories(Editor PRIVATE
|
||||
|
4
main.cpp
4
main.cpp
@ -10,10 +10,10 @@
|
||||
int main()
|
||||
{
|
||||
|
||||
OX::Core core("Application");
|
||||
OX::Core core("Obsidian Editor - Onyx Engine (2025.1)(0.0.4)");
|
||||
|
||||
|
||||
core.AddLayer(std::make_unique<OX::Editor>("Application"));
|
||||
core.AddLayer(std::make_unique<OX::Editor>("Obsidian Editor"));
|
||||
|
||||
|
||||
core.Init();
|
||||
|
@ -3,6 +3,9 @@
|
||||
//
|
||||
|
||||
#include "Core.h"
|
||||
|
||||
#include "systems/MACROS.h"
|
||||
|
||||
namespace OX
|
||||
{
|
||||
|
||||
@ -19,8 +22,8 @@ void Core::Init() {
|
||||
|
||||
|
||||
|
||||
|
||||
for (auto& layer : m_layers) {
|
||||
OX_ASSERT(!m_layers.empty(), "No Layers Attached");
|
||||
for (const auto& layer : m_layers) {
|
||||
Logger::LogDebug("Initializing Layer: '%s'", layer->GetName().c_str());
|
||||
layer->Init(*this);
|
||||
}
|
||||
@ -35,7 +38,7 @@ void Core::Run() {
|
||||
while (!window.ShouldClose()) {
|
||||
Profiler::BeginFrame();
|
||||
{
|
||||
PROFILE_LABEL("Frame");
|
||||
OX_PROFILE_LABEL("Frame");
|
||||
Update();
|
||||
window.BeginFrame();
|
||||
|
||||
@ -52,14 +55,14 @@ void Core::Run() {
|
||||
}
|
||||
|
||||
void Core::Update() {
|
||||
PROFILE_FUNCTION();
|
||||
OX_PROFILE_FUNCTION();
|
||||
for (auto& layer : m_layers) {
|
||||
layer->Update(*this);
|
||||
}
|
||||
}
|
||||
|
||||
void Core::Draw() {
|
||||
PROFILE_FUNCTION();
|
||||
OX_PROFILE_FUNCTION();
|
||||
|
||||
|
||||
for (auto& layer : m_layers) {
|
||||
@ -82,4 +85,4 @@ void Core::Shutdown() {
|
||||
|
||||
Logger::LogOk("Core Shutdown Complete.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "systems/Logger.h"
|
||||
#include "systems/Profiler.h"
|
||||
#include "systems/WindowManager.h"
|
||||
#include "systems/MACROS.h"
|
||||
|
||||
namespace OX
|
||||
{
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <chrono>
|
||||
#include <ctime>
|
||||
#include <cstdarg>
|
||||
|
||||
namespace OX
|
||||
{
|
||||
std::vector<Message> Logger::m_messages;
|
||||
@ -137,4 +138,19 @@ namespace OX
|
||||
const std::vector<Message>& Logger::GetMessages() {
|
||||
return m_messages;
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::string Logger::MessageTypeToString(const MessageType type) {
|
||||
switch (type) {
|
||||
case MessageType::Info: return "Info";
|
||||
case MessageType::Warning: return "Warning";
|
||||
case MessageType::Error: return "Error";
|
||||
case MessageType::Debug: return "Debug";
|
||||
case MessageType::Ok: return "Ok";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -5,6 +5,8 @@
|
||||
#include <cstdarg>
|
||||
namespace OX
|
||||
{
|
||||
|
||||
|
||||
enum class MessageType {
|
||||
Info,
|
||||
Warning,
|
||||
@ -30,6 +32,10 @@ public:
|
||||
static void LogDebug(const char* format, ...);
|
||||
static void LogOk(const char* format, ...);
|
||||
|
||||
static void Clear() {m_messages.clear();}
|
||||
|
||||
static std::string MessageTypeToString(const MessageType type);
|
||||
|
||||
|
||||
static const std::vector<Message>& GetMessages();
|
||||
|
||||
|
48
src/core/systems/MACROS.h
Normal file
48
src/core/systems/MACROS.h
Normal file
@ -0,0 +1,48 @@
|
||||
//
|
||||
// Created by spenc on 5/18/2025.
|
||||
//
|
||||
|
||||
#ifndef MACROS_H
|
||||
#define MACROS_H
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define OX_DEBUG_BREAK() __debugbreak()
|
||||
#elif defined(__unix__) || defined(__APPLE__)
|
||||
#include <signal.h>
|
||||
#define OX_DEBUG_BREAK() raise(SIGTRAP)
|
||||
#else
|
||||
#define OX_DEBUG_BREAK() ((void)0)
|
||||
#endif
|
||||
|
||||
// ========== ASSERT ==========
|
||||
// In debug builds: breaks and logs.
|
||||
// In release builds: removed entirely.
|
||||
#ifdef _DEBUG
|
||||
#define OX_ASSERT(condition, message) \
|
||||
do { \
|
||||
if (!(condition)) { \
|
||||
std::cerr << "\n[ASSERTION] " << #condition << "\n" \
|
||||
<< "Message: " << message << "\n" \
|
||||
<< "File: " << __FILE__ << ":" << __LINE__ << "\n"; \
|
||||
OX_DEBUG_BREAK(); \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
#define OX_ASSERT(condition, message) ((void)0)
|
||||
#endif
|
||||
|
||||
// ========== VERIFY ==========
|
||||
// In debug builds: asserts.
|
||||
// In release builds: just evaluates the condition.
|
||||
#ifdef _DEBUG
|
||||
#define OX_VERIFY(condition, message) OX_ASSERT(condition, message)
|
||||
#else
|
||||
#define OX_VERIFY(condition, message) ((void)(condition))
|
||||
#endif
|
||||
|
||||
|
||||
#endif //MACROS_H
|
@ -58,13 +58,13 @@ namespace OX
|
||||
|
||||
#if defined(_DEBUG) || defined(DEBUG)
|
||||
|
||||
#define PROFILE_FUNCTION() ProfileScope __profile_scope__##__LINE__(__FUNC_NAME__)
|
||||
#define PROFILE_LABEL(name) ProfileScope __profile_scope__##__LINE__(name)
|
||||
#define OX_PROFILE_FUNCTION() ProfileScope __profile_scope__##__LINE__(__FUNC_NAME__)
|
||||
#define OX_PROFILE_LABEL(name) ProfileScope __profile_scope__##__LINE__(name)
|
||||
|
||||
#else
|
||||
|
||||
#define PROFILE_FUNCTION()
|
||||
#define PROFILE_LABEL(name)
|
||||
#define OX_PROFILE_FUNCTION()
|
||||
#define OX_PROFILE_LABEL(name)
|
||||
|
||||
#endif
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ bool WindowManager::Init(const std::string& title, int width, int height) {
|
||||
|
||||
|
||||
void WindowManager::FramebufferSizeCallback(GLFWwindow* window, int width, int height) {
|
||||
PROFILE_FUNCTION();
|
||||
OX_PROFILE_FUNCTION();
|
||||
|
||||
auto* wm = static_cast<WindowManager*>(glfwGetWindowUserPointer(window));
|
||||
if (wm) {
|
||||
@ -58,7 +58,7 @@ void WindowManager::FramebufferSizeCallback(GLFWwindow* window, int width, int h
|
||||
}
|
||||
|
||||
void WindowManager::SetSize(int width, int height) {
|
||||
PROFILE_FUNCTION();
|
||||
OX_PROFILE_FUNCTION();
|
||||
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
@ -66,7 +66,7 @@ void WindowManager::SetSize(int width, int height) {
|
||||
}
|
||||
|
||||
void WindowManager::PollEvents() const {
|
||||
PROFILE_FUNCTION();
|
||||
OX_PROFILE_FUNCTION();
|
||||
|
||||
glfwPollEvents();
|
||||
}
|
||||
@ -76,7 +76,7 @@ bool WindowManager::ShouldClose() const {
|
||||
}
|
||||
|
||||
void WindowManager::BeginFrame() const {
|
||||
PROFILE_FUNCTION();
|
||||
OX_PROFILE_FUNCTION();
|
||||
PollEvents();
|
||||
glViewport(0, 0, m_width, m_height);
|
||||
glClearColor(0.07f, 0.07f, 0.1f, 1.0f);
|
||||
@ -84,10 +84,10 @@ void WindowManager::BeginFrame() const {
|
||||
}
|
||||
|
||||
void WindowManager::EndFrame() const {
|
||||
OX_PROFILE_FUNCTION();
|
||||
|
||||
glfwSwapBuffers(m_window);
|
||||
|
||||
{
|
||||
glfwSwapBuffers(m_window);
|
||||
}
|
||||
}
|
||||
|
||||
void WindowManager::Shutdown() {
|
||||
|
@ -3,27 +3,132 @@
|
||||
//
|
||||
|
||||
#include "Editor.h"
|
||||
|
||||
#include <functional>
|
||||
#include <imgui.h>
|
||||
#include <imgui_impl_opengl3.h>
|
||||
#include <imgui_impl_glfw.h>
|
||||
#include "Windows/LoggerWindow.h"
|
||||
namespace OX {
|
||||
|
||||
void Editor::Init(Core& core)
|
||||
{
|
||||
Logger::LogOk("Editor::Init");
|
||||
Logger::LogInfo("%s Init", m_name.c_str());
|
||||
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
|
||||
|
||||
ImGui::StyleColorsDark();
|
||||
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) {
|
||||
style.WindowRounding = 5.0f;
|
||||
style.Colors[ImGuiCol_WindowBg].w = 1.0f;
|
||||
}
|
||||
|
||||
ImGui_ImplGlfw_InitForOpenGL(core.GetWindow().GetHandle(), true);
|
||||
ImGui_ImplOpenGL3_Init("#version 330 core");
|
||||
}
|
||||
|
||||
void Editor::Update(Core& core)
|
||||
{
|
||||
OX_PROFILE_FUNCTION();
|
||||
|
||||
}
|
||||
|
||||
void Editor::Draw(Core& core)
|
||||
{
|
||||
|
||||
OX_PROFILE_FUNCTION();
|
||||
|
||||
|
||||
ImGui_ImplOpenGL3_NewFrame();
|
||||
ImGui_ImplGlfw_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
|
||||
|
||||
|
||||
// === Main Docking Space ===
|
||||
ImGuiWindowFlags windowFlags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoBackground;
|
||||
|
||||
const ImGuiViewport* viewport = ImGui::GetMainViewport();
|
||||
ImGui::SetNextWindowPos(viewport->WorkPos);
|
||||
ImGui::SetNextWindowSize(viewport->WorkSize);
|
||||
ImGui::SetNextWindowViewport(viewport->ID);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
|
||||
windowFlags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove;
|
||||
windowFlags |= ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus;
|
||||
|
||||
ImGui::Begin("DockSpace Root", nullptr, windowFlags);
|
||||
ImGui::PopStyleVar(2);
|
||||
|
||||
ImGuiID dockspaceID = ImGui::GetID("MyDockSpace");
|
||||
ImGui::DockSpace(dockspaceID, ImVec2(0.0f, 0.0f), ImGuiDockNodeFlags_PassthruCentralNode);
|
||||
|
||||
LoggerWindow::Draw();
|
||||
|
||||
|
||||
ImGui::Begin("Profiler");
|
||||
|
||||
const auto& tree = Profiler::GetSavedTree();
|
||||
if (tree.empty()) {
|
||||
ImGui::Text("No samples yet.");
|
||||
} else {
|
||||
std::function<void(const Profiler::SavedSample&, int)> DrawNode;
|
||||
DrawNode = [&](const Profiler::SavedSample& node, int depth) {
|
||||
// Indentation
|
||||
ImGui::Indent(depth * 10.0f);
|
||||
|
||||
// Color based on 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.2f, 1.0f, 0.2f, 1.0f); // green
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, color);
|
||||
|
||||
ImGui::Text("%s (%d): %.2f ms", node.name.c_str(), node.callCount, node.totalTime);
|
||||
|
||||
ImGui::PopStyleColor();
|
||||
for (const auto& child : node.children) {
|
||||
DrawNode(child, depth + 1);
|
||||
}
|
||||
|
||||
ImGui::Unindent(depth * 10.0f);
|
||||
};
|
||||
|
||||
for (const auto& root : tree) {
|
||||
DrawNode(root, 0);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
|
||||
ImGui::End(); // DockSpace Root
|
||||
|
||||
// --- Render ImGui onto FBO 0 ---
|
||||
{
|
||||
OX_PROFILE_LABEL("VSYNC Wait");
|
||||
|
||||
ImGui::EndFrame();
|
||||
ImGui::Render();
|
||||
ImGui::UpdatePlatformWindows();
|
||||
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Editor::Shutdown(Core& core)
|
||||
{
|
||||
Logger::LogOk("Editor::Shutdown");
|
||||
ImGui_ImplOpenGL3_Shutdown();
|
||||
ImGui_ImplGlfw_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
|
||||
|
||||
}
|
||||
|
150
src/editor/Windows/LoggerWindow.cpp
Normal file
150
src/editor/Windows/LoggerWindow.cpp
Normal file
@ -0,0 +1,150 @@
|
||||
//
|
||||
// Created by spenc on 5/12/2025.
|
||||
//
|
||||
|
||||
#include "LoggerWindow.h"
|
||||
#include "Core.h"
|
||||
#include <imgui.h>
|
||||
#include <string>
|
||||
|
||||
|
||||
|
||||
|
||||
namespace OX::LoggerWindow {
|
||||
|
||||
static bool s_AutoScroll = true;
|
||||
static bool s_ShowOk = true;
|
||||
static bool s_ShowInfo = true;
|
||||
static bool s_ShowWarning = true;
|
||||
static bool s_ShowError = true;
|
||||
static bool s_ShowDebug = false;
|
||||
static bool s_ShowVerbose = false;
|
||||
static char s_FilterBuf[256] = "";
|
||||
|
||||
static ImVec4 GetColor(const MessageType level) {
|
||||
switch (level) {
|
||||
case MessageType::Ok: return {0.6f, 1.0f, 0.6f, 1.0f};
|
||||
case MessageType::Info: return {0.3f, 0.6f, 1.0f, 1.0f};
|
||||
case MessageType::Warning: return {1.0f, 0.8f, 0.2f, 1.0f};
|
||||
case MessageType::Error: return {1.0f, 0.2f, 0.2f, 1.0f};
|
||||
case MessageType::Debug: return {0.2f, 1.0f, 1.0f, 1.0f};
|
||||
default: return {1, 1, 1, 1};
|
||||
}
|
||||
}
|
||||
|
||||
void Draw(const char* title)
|
||||
{
|
||||
OX_PROFILE_FUNCTION();
|
||||
|
||||
if (!ImGui::Begin(title)) {
|
||||
ImGui::End();
|
||||
return;
|
||||
}
|
||||
|
||||
// Controls
|
||||
if (ImGui::Button("Clear Log")) Logger::Clear();
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox("Auto-scroll", &s_AutoScroll);
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(200);
|
||||
ImGui::InputTextWithHint("##Filter", "Filter...", s_FilterBuf, sizeof(s_FilterBuf));
|
||||
|
||||
// Filter toggles
|
||||
ImGui::Separator();
|
||||
ImGui::Text("Levels: ");
|
||||
ImGui::SameLine(); ImGui::Checkbox("Ok", &s_ShowOk);
|
||||
ImGui::SameLine(); ImGui::Checkbox("Info", &s_ShowInfo);
|
||||
ImGui::SameLine(); ImGui::Checkbox("Warning", &s_ShowWarning);
|
||||
ImGui::SameLine(); ImGui::Checkbox("Error", &s_ShowError);
|
||||
ImGui::SameLine(); ImGui::Checkbox("Debug", &s_ShowDebug);
|
||||
ImGui::SameLine(); ImGui::Checkbox("Verbose", &s_ShowVerbose);
|
||||
ImGui::Separator();
|
||||
|
||||
constexpr ImGuiTableFlags flags =
|
||||
ImGuiTableFlags_Resizable | ImGuiTableFlags_RowBg |
|
||||
ImGuiTableFlags_ScrollY | ImGuiTableFlags_BordersOuter;
|
||||
|
||||
if (const float tableHeight = ImGui::GetContentRegionAvail().y - 10.0f; ImGui::BeginTable("LogTable", 3, flags, ImVec2(0, tableHeight))) {
|
||||
ImGui::TableSetupColumn("Level", ImGuiTableColumnFlags_WidthFixed, 80.0f);
|
||||
ImGui::TableSetupColumn("Time", ImGuiTableColumnFlags_WidthFixed, 80.0f);
|
||||
ImGui::TableSetupColumn("Message", ImGuiTableColumnFlags_WidthStretch);
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
for (const auto& message : Logger::GetMessages()) {
|
||||
const MessageType level = message.type;
|
||||
const std::string& text = message.text;
|
||||
const std::string& timestamp = message.timestamp;
|
||||
|
||||
const bool show =
|
||||
(level == MessageType::Ok && s_ShowOk) ||
|
||||
(level == MessageType::Info && s_ShowInfo) ||
|
||||
(level == MessageType::Warning && s_ShowWarning) ||
|
||||
(level == MessageType::Error && s_ShowError) ||
|
||||
(level == MessageType::Debug && s_ShowDebug);
|
||||
|
||||
if (!show)
|
||||
continue;
|
||||
|
||||
if (s_FilterBuf[0] != '\0' &&
|
||||
std::string(text).find(s_FilterBuf) == std::string::npos)
|
||||
continue;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ImGui::TableNextRow();
|
||||
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
ImVec4 col = GetColor(level);
|
||||
const ImVec2 cursor = ImGui::GetCursorScreenPos();
|
||||
constexpr float barWidth = 4.0f;
|
||||
const float textHeight = ImGui::GetTextLineHeight();
|
||||
ImVec2 barStart = cursor;
|
||||
auto barEnd = ImVec2(cursor.x + barWidth, cursor.y + textHeight);
|
||||
ImGui::GetWindowDrawList()->AddRectFilled(barStart, barEnd, ImGui::ColorConvertFloat4ToU32(col), 1.0f);
|
||||
|
||||
ImGui::Dummy(ImVec2(barWidth + 6.0f, 0));
|
||||
ImGui::SameLine();
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, col);
|
||||
ImGui::TextUnformatted(Logger::MessageTypeToString(level).c_str());
|
||||
ImGui::PopStyleColor();
|
||||
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
ImGui::Text("%s",timestamp.c_str());
|
||||
|
||||
ImGui::TableSetColumnIndex(2);
|
||||
ImGui::TextWrapped("%s", text.c_str());
|
||||
|
||||
|
||||
|
||||
if (s_AutoScroll) {
|
||||
if (ImGui::GetScrollY() >= ImGui::GetScrollMaxY() - 5.0f) {
|
||||
ImGui::SetScrollHereY(1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void ClearFilters() {
|
||||
s_FilterBuf[0] = '\0';
|
||||
s_ShowOk = s_ShowInfo = s_ShowWarning = s_ShowError = s_ShowDebug = s_ShowVerbose = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// CE
|
17
src/editor/Windows/LoggerWindow.h
Normal file
17
src/editor/Windows/LoggerWindow.h
Normal file
@ -0,0 +1,17 @@
|
||||
//
|
||||
// Created by spenc on 5/18/2025.
|
||||
//
|
||||
|
||||
#ifndef LOGGERWINDOW_H
|
||||
#define LOGGERWINDOW_H
|
||||
|
||||
namespace OX {
|
||||
|
||||
namespace LoggerWindow {
|
||||
void Draw(const char* title = "Console");
|
||||
void ClearFilters();
|
||||
};
|
||||
|
||||
} // OX
|
||||
|
||||
#endif //LOGGERWINDOW_H
|
Loading…
Reference in New Issue
Block a user