Fixed Logger and Brought back Verbose
This commit is contained in:
parent
5ad82a1368
commit
36b821eb64
@ -1,5 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(CreatePBR VERSION 0.1.0 LANGUAGES C CXX)
|
||||
project(Onyx VERSION 0.1.0 LANGUAGES C CXX)
|
||||
|
||||
# Build type (for single-config generators like Make/Ninja)
|
||||
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||
|
@ -8,81 +8,87 @@
|
||||
|
||||
namespace OX
|
||||
{
|
||||
|
||||
void Core::AddLayer(std::unique_ptr<Layer> layer) {
|
||||
Logger::LogDebug("Added Layer: '%s'", layer->GetName().c_str());
|
||||
m_layers.emplace_back(std::move(layer));
|
||||
}
|
||||
|
||||
void Core::Init() {
|
||||
Logger::LogInfo("Initializing Core...");
|
||||
|
||||
if (!window.Init(m_name, 1280, 720))
|
||||
return;
|
||||
|
||||
|
||||
|
||||
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);
|
||||
void Core::AddLayer(std::unique_ptr<Layer> layer)
|
||||
{
|
||||
Logger::LogDebug("Added Layer: '%s'", layer->GetName().c_str());
|
||||
m_layers.emplace_back(std::move(layer));
|
||||
}
|
||||
|
||||
void Core::Init()
|
||||
{
|
||||
Logger::LogInfo("Initializing Core...");
|
||||
|
||||
Logger::LogOk("Core Initialization Complete.");
|
||||
}
|
||||
if (!window.Init(m_name, 1280, 720))
|
||||
return;
|
||||
|
||||
void Core::Run() {
|
||||
m_running = true;
|
||||
|
||||
while (!window.ShouldClose()) {
|
||||
Profiler::BeginFrame();
|
||||
{
|
||||
OX_PROFILE_LABEL("Frame");
|
||||
Update();
|
||||
window.BeginFrame();
|
||||
|
||||
Draw();
|
||||
window.EndFrame();
|
||||
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);
|
||||
}
|
||||
Profiler::EndFrame();
|
||||
|
||||
|
||||
Logger::LogOk("Core Initialization Complete.");
|
||||
|
||||
Logger::LogInfo("Info: This is an informational message.");
|
||||
Logger::LogWarning("Warning: Something might be wrong.");
|
||||
Logger::LogError("Error: Something went wrong!");
|
||||
Logger::LogDebug("Debug: Internal debug information.");
|
||||
Logger::LogVerbose("Verbose: Extra detailed logs.");
|
||||
Logger::LogOk("Ok: Everything succeeded!");
|
||||
}
|
||||
|
||||
|
||||
void Core::Run()
|
||||
{
|
||||
m_running = true;
|
||||
|
||||
while (!window.ShouldClose()) {
|
||||
Profiler::BeginFrame(); {
|
||||
OX_PROFILE_LABEL("Frame");
|
||||
Update();
|
||||
window.BeginFrame();
|
||||
|
||||
}
|
||||
|
||||
void Core::Update() {
|
||||
OX_PROFILE_FUNCTION();
|
||||
for (auto& layer : m_layers) {
|
||||
layer->Update(*this);
|
||||
}
|
||||
}
|
||||
|
||||
void Core::Draw() {
|
||||
OX_PROFILE_FUNCTION();
|
||||
|
||||
|
||||
for (auto& layer : m_layers) {
|
||||
layer->Draw(*this);
|
||||
}
|
||||
}
|
||||
|
||||
void Core::Shutdown() {
|
||||
Logger::LogDebug("Shutting down Core...");
|
||||
|
||||
|
||||
for (auto& layer : m_layers) {
|
||||
Logger::LogDebug("Shutting down Layer: '%s'", layer->GetName().c_str());
|
||||
layer->Shutdown(*this);
|
||||
Draw();
|
||||
window.EndFrame();
|
||||
}
|
||||
Profiler::EndFrame();
|
||||
}
|
||||
}
|
||||
|
||||
m_layers.clear();
|
||||
void Core::Update()
|
||||
{
|
||||
OX_PROFILE_FUNCTION();
|
||||
for (auto &layer: m_layers) {
|
||||
layer->Update(*this);
|
||||
}
|
||||
}
|
||||
|
||||
window.Shutdown();
|
||||
void Core::Draw()
|
||||
{
|
||||
OX_PROFILE_FUNCTION();
|
||||
|
||||
Logger::LogOk("Core Shutdown Complete.");
|
||||
}
|
||||
|
||||
for (auto &layer: m_layers) {
|
||||
layer->Draw(*this);
|
||||
}
|
||||
}
|
||||
|
||||
void Core::Shutdown()
|
||||
{
|
||||
Logger::LogDebug("Shutting down Core...");
|
||||
|
||||
|
||||
for (auto &layer: m_layers) {
|
||||
Logger::LogDebug("Shutting down Layer: '%s'", layer->GetName().c_str());
|
||||
layer->Shutdown(*this);
|
||||
}
|
||||
|
||||
m_layers.clear();
|
||||
|
||||
window.Shutdown();
|
||||
|
||||
Logger::LogOk("Core Shutdown Complete.");
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include <chrono>
|
||||
#include <ctime>
|
||||
#include <cstdarg>
|
||||
|
||||
#include "types/all.h"
|
||||
namespace OX
|
||||
{
|
||||
std::vector<Message> Logger::m_messages;
|
||||
@ -15,6 +15,7 @@ namespace OX
|
||||
case MessageType::Error: return "Error";
|
||||
case MessageType::Debug: return "Debug";
|
||||
case MessageType::Ok: return "Ok";
|
||||
case MessageType::Verbose: return "Verbose";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
@ -32,31 +33,52 @@ namespace OX
|
||||
|
||||
static const char* GetAnsiColor(MessageType type) {
|
||||
switch (type) {
|
||||
case MessageType::Info: return "\033[1;34m";
|
||||
case MessageType::Warning: return "\033[1;33m";
|
||||
case MessageType::Error: return "\033[1;31m";
|
||||
case MessageType::Debug: return "\033[1;90m";
|
||||
case MessageType::Ok: return "\033[1;32m";
|
||||
default: return "\033[0m";
|
||||
case MessageType::Info: return "\033[1;36m"; // Bright cyan
|
||||
case MessageType::Warning: return "\033[1;33m"; // Bright yellow
|
||||
case MessageType::Error: return "\033[1;91m"; // Bright red
|
||||
case MessageType::Debug: return "\033[1;90m"; // Bright gray
|
||||
case MessageType::Verbose: return "\033[0;37m"; // Standard gray (lighter than debug)
|
||||
case MessageType::Ok: return "\033[1;32m"; // Bright green
|
||||
default: return "\033[0m"; // Reset
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void GetRGBColor(MessageType type, float& r, float& g, float& b) {
|
||||
Color Logger::GetRGBColor(const MessageType type) {
|
||||
Color color;
|
||||
switch (type) {
|
||||
case MessageType::Info: r = 0.2f; g = 0.6f; b = 1.0f; break;
|
||||
case MessageType::Warning: r = 1.0f; g = 0.8f; b = 0.2f; break;
|
||||
case MessageType::Error: r = 1.0f; g = 0.2f; b = 0.2f; break;
|
||||
case MessageType::Debug: r = 0.7f; g = 0.7f; b = 0.7f; break;
|
||||
case MessageType::Ok: r = 0.6f; g = 1.0f; b = 0.6f; break;
|
||||
default: r = g = b = 1.0f; break;
|
||||
case MessageType::Info:
|
||||
color.r = 0.25f; color.g = 0.5f; color.b = 0.95f; // Calmer blue
|
||||
break;
|
||||
case MessageType::Warning:
|
||||
color.r = 1.0f; color.g = 0.75f; color.b = 0.1f; // Amber/goldenrod
|
||||
break;
|
||||
case MessageType::Error:
|
||||
color.r = 0.9f; color.g = 0.2f; color.b = 0.3f; // Strong crimson red
|
||||
break;
|
||||
case MessageType::Debug:
|
||||
color.r = 0.6f; color.g = 0.6f; color.b = 0.7f; // Neutral cool gray
|
||||
break;
|
||||
case MessageType::Ok:
|
||||
color.r = 0.3f; color.g = 0.85f; color.b = 0.4f; // Balanced green
|
||||
break;
|
||||
case MessageType::Verbose:
|
||||
color.r = 0.7f; color.g = 0.7f; color.b = 0.9f; // Soft lavender/gray
|
||||
break;
|
||||
default:
|
||||
color = Color::White(); // Default white
|
||||
break;
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
|
||||
void Logger::LogInternal(const std::string& text, MessageType type) {
|
||||
float r, g, b;
|
||||
GetRGBColor(type, r, g, b);
|
||||
glm::vec3 color = Logger::GetRGBColor(type);
|
||||
float r = color.r;
|
||||
float g = color.g;
|
||||
float b = color.b;
|
||||
|
||||
|
||||
Message message {
|
||||
GetTimestamp(),
|
||||
@ -126,6 +148,16 @@ namespace OX
|
||||
LogInternal(buffer, MessageType::Debug);
|
||||
}
|
||||
|
||||
void Logger::LogVerbose(const char* format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
char buffer[1024];
|
||||
std::vsnprintf(buffer, sizeof(buffer), format, args);
|
||||
va_end(args);
|
||||
LogInternal(buffer, MessageType::Verbose);
|
||||
}
|
||||
|
||||
|
||||
void Logger::LogOk(const char* format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
@ -147,6 +179,7 @@ namespace OX
|
||||
case MessageType::Warning: return "Warning";
|
||||
case MessageType::Error: return "Error";
|
||||
case MessageType::Debug: return "Debug";
|
||||
case MessageType::Verbose: return "Verbose";
|
||||
case MessageType::Ok: return "Ok";
|
||||
default: return "Unknown";
|
||||
}
|
||||
|
@ -3,6 +3,8 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <cstdarg>
|
||||
#include <types/color.h>
|
||||
|
||||
namespace OX
|
||||
{
|
||||
|
||||
@ -12,6 +14,7 @@ enum class MessageType {
|
||||
Warning,
|
||||
Error,
|
||||
Debug,
|
||||
Verbose,
|
||||
Ok
|
||||
};
|
||||
|
||||
@ -30,11 +33,13 @@ public:
|
||||
static void LogWarning(const char* format, ...);
|
||||
static void LogError(const char* format, ...);
|
||||
static void LogDebug(const char* format, ...);
|
||||
static void LogVerbose(const char* format, ...);
|
||||
static void LogOk(const char* format, ...);
|
||||
|
||||
static void Clear() {m_messages.clear();}
|
||||
|
||||
static std::string MessageTypeToString(const MessageType type);
|
||||
static std::string MessageTypeToString(MessageType type);
|
||||
static Color GetRGBColor(MessageType type);
|
||||
|
||||
|
||||
static const std::vector<Message>& GetMessages();
|
||||
@ -43,4 +48,4 @@ private:
|
||||
static void LogInternal(const std::string& text, MessageType type);
|
||||
static std::vector<Message> m_messages;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
11
src/core/types/all.h
Normal file
11
src/core/types/all.h
Normal file
@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
static constexpr float PI = 3.14159265358979323846f;
|
||||
|
||||
|
||||
#include "color.h"
|
||||
#include "rect.h"
|
||||
#include "vec2.h"
|
||||
#include "vec3.h"
|
||||
#include "vec4.h"
|
||||
#include "mat4.h"
|
173
src/core/types/color.h
Normal file
173
src/core/types/color.h
Normal file
@ -0,0 +1,173 @@
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <glm/glm.hpp>
|
||||
#ifdef IMGUI_VERSION
|
||||
#include <imgui.h>
|
||||
#define HAS_IMGUI
|
||||
#endif
|
||||
|
||||
namespace OX
|
||||
{
|
||||
|
||||
struct Color
|
||||
{
|
||||
float r, g, b, a;
|
||||
|
||||
// Constructors
|
||||
constexpr Color() noexcept : r(1), g(1), b(1), a(1) {}
|
||||
constexpr Color(float _r, float _g, float _b, float _a = 1.0f) noexcept
|
||||
: r(_r), g(_g), b(_b), a(_a) {}
|
||||
Color(const glm::vec3 &v, float _a = 1.0f) : r(v.x), g(v.y), b(v.z), a(_a) {}
|
||||
Color(const glm::vec4 &v) : r(v.x), g(v.y), b(v.z), a(v.w) {}
|
||||
|
||||
// Conversion operators
|
||||
operator glm::vec3() const { return {r, g, b}; }
|
||||
operator glm::vec4() const { return {r, g, b, a}; }
|
||||
|
||||
#ifdef HAS_IMGUI
|
||||
operator ImVec3() const { return {r, g, b}; }
|
||||
operator ImVec4() const { return {r, g, b, a}; }
|
||||
#endif
|
||||
|
||||
|
||||
// Arithmetic
|
||||
Color operator+(const Color &o) const { return {r + o.r, g + o.g, b + o.b, a + o.a}; }
|
||||
Color &operator+=(const Color &o)
|
||||
{
|
||||
r += o.r;
|
||||
g += o.g;
|
||||
b += o.b;
|
||||
a += o.a;
|
||||
return *this;
|
||||
}
|
||||
Color operator-(const Color &o) const { return {r - o.r, g - o.g, b - o.b, a - o.a}; }
|
||||
Color &operator-=(const Color &o)
|
||||
{
|
||||
r -= o.r;
|
||||
g -= o.g;
|
||||
b -= o.b;
|
||||
a -= o.a;
|
||||
return *this;
|
||||
}
|
||||
Color operator*(const Color &o) const { return {r * o.r, g * o.g, b * o.b, a * o.a}; }
|
||||
Color &operator*=(const Color &o)
|
||||
{
|
||||
r *= o.r;
|
||||
g *= o.g;
|
||||
b *= o.b;
|
||||
a *= o.a;
|
||||
return *this;
|
||||
}
|
||||
Color operator*(float s) const { return {r * s, g * s, b * s, a * s}; }
|
||||
Color &operator*=(float s)
|
||||
{
|
||||
r *= s;
|
||||
g *= s;
|
||||
b *= s;
|
||||
a *= s;
|
||||
return *this;
|
||||
}
|
||||
Color operator/(float s) const
|
||||
{
|
||||
float inv = 1.0f / s;
|
||||
return {r * inv, g * inv, b * inv, a * inv};
|
||||
}
|
||||
Color &operator/=(float s)
|
||||
{
|
||||
float inv = 1.0f / s;
|
||||
r *= inv;
|
||||
g *= inv;
|
||||
b *= inv;
|
||||
a *= inv;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const Color &o) const { return r == o.r && g == o.g && b == o.b && a == o.a; }
|
||||
bool operator!=(const Color &o) const { return !(*this == o); }
|
||||
|
||||
// Utilities
|
||||
static Color Lerp(const Color &a, const Color &b, float t)
|
||||
{
|
||||
return a + (b - a) * t;
|
||||
}
|
||||
|
||||
void Clamp()
|
||||
{
|
||||
r = std::clamp(r, 0.0f, 1.0f);
|
||||
g = std::clamp(g, 0.0f, 1.0f);
|
||||
b = std::clamp(b, 0.0f, 1.0f);
|
||||
a = std::clamp(a, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
Color WithAlpha(float alpha) const { return {r, g, b, alpha}; }
|
||||
Color Inverted() const { return {1.0f - r, 1.0f - g, 1.0f - b, a}; }
|
||||
Color Grayscale() const
|
||||
{
|
||||
float gray = (r + g + b) / 3.0f;
|
||||
return {gray, gray, gray, a};
|
||||
}
|
||||
|
||||
std::string ToHexString(bool includeAlpha = false) const
|
||||
{
|
||||
auto toU8 = [&](float x)
|
||||
{ return static_cast<int>(std::clamp(x, 0.0f, 1.0f) * 255.0f); };
|
||||
std::ostringstream oss;
|
||||
oss << std::hex << std::setw(2) << std::setfill('0') << toU8(r)
|
||||
<< std::setw(2) << std::setfill('0') << toU8(g)
|
||||
<< std::setw(2) << std::setfill('0') << toU8(b);
|
||||
if (includeAlpha)
|
||||
{
|
||||
oss << std::setw(2) << std::setfill('0') << toU8(a);
|
||||
}
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
static Color FromHexString(const std::string &hex)
|
||||
{
|
||||
unsigned int v = 0;
|
||||
std::stringstream ss;
|
||||
ss << std::hex << hex;
|
||||
ss >> v;
|
||||
if (hex.size() <= 6)
|
||||
{
|
||||
return {((v >> 16) & 0xFF) / 255.0f,
|
||||
((v >> 8) & 0xFF) / 255.0f,
|
||||
(v & 0xFF) / 255.0f,
|
||||
1.0f};
|
||||
}
|
||||
return {((v >> 24) & 0xFF) / 255.0f,
|
||||
((v >> 16) & 0xFF) / 255.0f,
|
||||
((v >> 8) & 0xFF) / 255.0f,
|
||||
(v & 0xFF) / 255.0f};
|
||||
}
|
||||
|
||||
// Common color factories
|
||||
static constexpr Color White(float alpha = 1.0f) noexcept { return {1.0f, 1.0f, 1.0f, alpha}; }
|
||||
static constexpr Color Black(float alpha = 1.0f) noexcept { return {0.0f, 0.0f, 0.0f, alpha}; }
|
||||
static constexpr Color Red(float alpha = 1.0f) noexcept { return {1.0f, 0.0f, 0.0f, alpha}; }
|
||||
static constexpr Color Green(float alpha = 1.0f) noexcept { return {0.0f, 1.0f, 0.0f, alpha}; }
|
||||
static constexpr Color Blue(float alpha = 1.0f) noexcept { return {0.0f, 0.0f, 1.0f, alpha}; }
|
||||
static constexpr Color Yellow(float alpha = 1.0f) noexcept { return {1.0f, 1.0f, 0.0f, alpha}; }
|
||||
static constexpr Color Magenta(float alpha = 1.0f) noexcept { return {1.0f, 0.0f, 1.0f, alpha}; }
|
||||
static constexpr Color Cyan(float alpha = 1.0f) noexcept { return {0.0f, 1.0f, 1.0f, alpha}; }
|
||||
static constexpr Color Gray(float alpha = 1.0f) noexcept { return {0.5f, 0.5f, 0.5f, alpha}; }
|
||||
static constexpr Color LightGray(float alpha = 1.0f) noexcept { return {0.75f, 0.75f, 0.75f, alpha}; }
|
||||
static constexpr Color DarkGray(float alpha = 1.0f) noexcept { return {0.25f, 0.25f, 0.25f, alpha}; }
|
||||
static constexpr Color Orange(float alpha = 1.0f) noexcept { return {1.0f, 0.5f, 0.0f, alpha}; }
|
||||
static constexpr Color Pink(float alpha = 1.0f) noexcept { return {1.0f, 0.4f, 0.7f, alpha}; }
|
||||
static constexpr Color Purple(float alpha = 1.0f) noexcept { return {0.6f, 0.0f, 0.6f, alpha}; }
|
||||
static constexpr Color Brown(float alpha = 1.0f) noexcept { return {0.6f, 0.3f, 0.0f, alpha}; }
|
||||
static constexpr Color Transparent() noexcept { return {0.0f, 0.0f, 0.0f, 0.0f}; }
|
||||
};
|
||||
|
||||
// Free function for scalar multiplication
|
||||
inline Color operator*(float s, const Color &c)
|
||||
{
|
||||
return c * s;
|
||||
}
|
||||
|
||||
} // namespace CE::types
|
197
src/core/types/mat4.h
Normal file
197
src/core/types/mat4.h
Normal file
@ -0,0 +1,197 @@
|
||||
//
|
||||
// Created by spenc on 5/13/2025.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cmath>
|
||||
#include <cstring> // memcpy
|
||||
#include "Vec3.h"
|
||||
|
||||
namespace OX {
|
||||
|
||||
struct alignas(16) Mat4 {
|
||||
float m[16];
|
||||
|
||||
// Constructs identity
|
||||
Mat4() {
|
||||
LoadIdentity();
|
||||
}
|
||||
|
||||
explicit Mat4(float diagonal) {
|
||||
LoadIdentity();
|
||||
m[0] = m[5] = m[10] = m[15] = diagonal;
|
||||
}
|
||||
|
||||
void LoadIdentity() {
|
||||
std::memset(m, 0, sizeof(m));
|
||||
m[0] = m[5] = m[10] = m[15] = 1.0f;
|
||||
}
|
||||
|
||||
float* Ptr() { return m; }
|
||||
const float* Ptr() const { return m; }
|
||||
|
||||
// Matrix multiplication (Mat4 * Mat4)
|
||||
Mat4 operator*(const Mat4& rhs) const {
|
||||
Mat4 result;
|
||||
for (int col = 0; col < 4; ++col) {
|
||||
for (int row = 0; row < 4; ++row) {
|
||||
result.m[col * 4 + row] =
|
||||
m[0 * 4 + row] * rhs.m[col * 4 + 0] +
|
||||
m[1 * 4 + row] * rhs.m[col * 4 + 1] +
|
||||
m[2 * 4 + row] * rhs.m[col * 4 + 2] +
|
||||
m[3 * 4 + row] * rhs.m[col * 4 + 3];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Create translation matrix
|
||||
static Mat4 Translate(const Vec3& t) {
|
||||
Mat4 result;
|
||||
result.m[12] = t.x;
|
||||
result.m[13] = t.y;
|
||||
result.m[14] = t.z;
|
||||
return result;
|
||||
}
|
||||
|
||||
// Create scale matrix
|
||||
static Mat4 Scale(const Vec3& s) {
|
||||
Mat4 result;
|
||||
result.m[0] = s.x;
|
||||
result.m[5] = s.y;
|
||||
result.m[10] = s.z;
|
||||
return result;
|
||||
}
|
||||
|
||||
// Rotation around X axis
|
||||
static Mat4 RotateX(float angleRadians) {
|
||||
Mat4 result;
|
||||
float c = std::cos(angleRadians);
|
||||
float s = std::sin(angleRadians);
|
||||
result.m[5] = c;
|
||||
result.m[6] = s;
|
||||
result.m[9] = -s;
|
||||
result.m[10] = c;
|
||||
return result;
|
||||
}
|
||||
|
||||
// Rotation around Y axis
|
||||
static Mat4 RotateY(float angleRadians) {
|
||||
Mat4 result;
|
||||
float c = std::cos(angleRadians);
|
||||
float s = std::sin(angleRadians);
|
||||
result.m[0] = c;
|
||||
result.m[2] = -s;
|
||||
result.m[8] = s;
|
||||
result.m[10] = c;
|
||||
return result;
|
||||
}
|
||||
|
||||
// Rotation around Z axis
|
||||
static Mat4 RotateZ(float angleRadians) {
|
||||
Mat4 result;
|
||||
float c = std::cos(angleRadians);
|
||||
float s = std::sin(angleRadians);
|
||||
result.m[0] = c;
|
||||
result.m[1] = s;
|
||||
result.m[4] = -s;
|
||||
result.m[5] = c;
|
||||
return result;
|
||||
}
|
||||
|
||||
static Mat4 Identity() {
|
||||
return Mat4();
|
||||
}
|
||||
|
||||
|
||||
Mat4 Inverse() const {
|
||||
float inv[16];
|
||||
|
||||
// Cofactor matrix
|
||||
#define MAT(r, c) m[(c) * 4 + (r)]
|
||||
#define INV(r, c) inv[(c) * 4 + (r)]
|
||||
|
||||
INV(0,0) = MAT(1,1) * MAT(2,2) * MAT(3,3) - MAT(1,1) * MAT(2,3) * MAT(3,2) -
|
||||
MAT(2,1) * MAT(1,2) * MAT(3,3) + MAT(2,1) * MAT(1,3) * MAT(3,2) +
|
||||
MAT(3,1) * MAT(1,2) * MAT(2,3) - MAT(3,1) * MAT(1,3) * MAT(2,2);
|
||||
|
||||
INV(0,1) = -MAT(0,1) * MAT(2,2) * MAT(3,3) + MAT(0,1) * MAT(2,3) * MAT(3,2) +
|
||||
MAT(2,1) * MAT(0,2) * MAT(3,3) - MAT(2,1) * MAT(0,3) * MAT(3,2) -
|
||||
MAT(3,1) * MAT(0,2) * MAT(2,3) + MAT(3,1) * MAT(0,3) * MAT(2,2);
|
||||
|
||||
INV(0,2) = MAT(0,1) * MAT(1,2) * MAT(3,3) - MAT(0,1) * MAT(1,3) * MAT(3,2) -
|
||||
MAT(1,1) * MAT(0,2) * MAT(3,3) + MAT(1,1) * MAT(0,3) * MAT(3,2) +
|
||||
MAT(3,1) * MAT(0,2) * MAT(1,3) - MAT(3,1) * MAT(0,3) * MAT(1,2);
|
||||
|
||||
INV(0,3) = -MAT(0,1) * MAT(1,2) * MAT(2,3) + MAT(0,1) * MAT(1,3) * MAT(2,2) +
|
||||
MAT(1,1) * MAT(0,2) * MAT(2,3) - MAT(1,1) * MAT(0,3) * MAT(2,2) -
|
||||
MAT(2,1) * MAT(0,2) * MAT(1,3) + MAT(2,1) * MAT(0,3) * MAT(1,2);
|
||||
|
||||
INV(1,0) = -MAT(1,0) * MAT(2,2) * MAT(3,3) + MAT(1,0) * MAT(2,3) * MAT(3,2) +
|
||||
MAT(2,0) * MAT(1,2) * MAT(3,3) - MAT(2,0) * MAT(1,3) * MAT(3,2) -
|
||||
MAT(3,0) * MAT(1,2) * MAT(2,3) + MAT(3,0) * MAT(1,3) * MAT(2,2);
|
||||
|
||||
INV(1,1) = MAT(0,0) * MAT(2,2) * MAT(3,3) - MAT(0,0) * MAT(2,3) * MAT(3,2) -
|
||||
MAT(2,0) * MAT(0,2) * MAT(3,3) + MAT(2,0) * MAT(0,3) * MAT(3,2) +
|
||||
MAT(3,0) * MAT(0,2) * MAT(2,3) - MAT(3,0) * MAT(0,3) * MAT(2,2);
|
||||
|
||||
INV(1,2) = -MAT(0,0) * MAT(1,2) * MAT(3,3) + MAT(0,0) * MAT(1,3) * MAT(3,2) +
|
||||
MAT(1,0) * MAT(0,2) * MAT(3,3) - MAT(1,0) * MAT(0,3) * MAT(3,2) -
|
||||
MAT(3,0) * MAT(0,2) * MAT(1,3) + MAT(3,0) * MAT(0,3) * MAT(1,2);
|
||||
|
||||
INV(1,3) = MAT(0,0) * MAT(1,2) * MAT(2,3) - MAT(0,0) * MAT(1,3) * MAT(2,2) -
|
||||
MAT(1,0) * MAT(0,2) * MAT(2,3) + MAT(1,0) * MAT(0,3) * MAT(2,2) +
|
||||
MAT(2,0) * MAT(0,2) * MAT(1,3) - MAT(2,0) * MAT(0,3) * MAT(1,2);
|
||||
|
||||
INV(2,0) = MAT(1,0) * MAT(2,1) * MAT(3,3) - MAT(1,0) * MAT(2,3) * MAT(3,1) -
|
||||
MAT(2,0) * MAT(1,1) * MAT(3,3) + MAT(2,0) * MAT(1,3) * MAT(3,1) +
|
||||
MAT(3,0) * MAT(1,1) * MAT(2,3) - MAT(3,0) * MAT(1,3) * MAT(2,1);
|
||||
|
||||
INV(2,1) = -MAT(0,0) * MAT(2,1) * MAT(3,3) + MAT(0,0) * MAT(2,3) * MAT(3,1) +
|
||||
MAT(2,0) * MAT(0,1) * MAT(3,3) - MAT(2,0) * MAT(0,3) * MAT(3,1) -
|
||||
MAT(3,0) * MAT(0,1) * MAT(2,3) + MAT(3,0) * MAT(0,3) * MAT(2,1);
|
||||
|
||||
INV(2,2) = MAT(0,0) * MAT(1,1) * MAT(3,3) - MAT(0,0) * MAT(1,3) * MAT(3,1) -
|
||||
MAT(1,0) * MAT(0,1) * MAT(3,3) + MAT(1,0) * MAT(0,3) * MAT(3,1) +
|
||||
MAT(3,0) * MAT(0,1) * MAT(1,3) - MAT(3,0) * MAT(0,3) * MAT(1,1);
|
||||
|
||||
INV(2,3) = -MAT(0,0) * MAT(1,1) * MAT(2,3) + MAT(0,0) * MAT(1,3) * MAT(2,1) +
|
||||
MAT(1,0) * MAT(0,1) * MAT(2,3) - MAT(1,0) * MAT(0,3) * MAT(2,1) -
|
||||
MAT(2,0) * MAT(0,1) * MAT(1,3) + MAT(2,0) * MAT(0,3) * MAT(1,1);
|
||||
|
||||
INV(3,0) = -MAT(1,0) * MAT(2,1) * MAT(3,2) + MAT(1,0) * MAT(2,2) * MAT(3,1) +
|
||||
MAT(2,0) * MAT(1,1) * MAT(3,2) - MAT(2,0) * MAT(1,2) * MAT(3,1) -
|
||||
MAT(3,0) * MAT(1,1) * MAT(2,2) + MAT(3,0) * MAT(1,2) * MAT(2,1);
|
||||
|
||||
INV(3,1) = MAT(0,0) * MAT(2,1) * MAT(3,2) - MAT(0,0) * MAT(2,2) * MAT(3,1) -
|
||||
MAT(2,0) * MAT(0,1) * MAT(3,2) + MAT(2,0) * MAT(0,2) * MAT(3,1) +
|
||||
MAT(3,0) * MAT(0,1) * MAT(2,2) - MAT(3,0) * MAT(0,2) * MAT(2,1);
|
||||
|
||||
INV(3,2) = -MAT(0,0) * MAT(1,1) * MAT(3,2) + MAT(0,0) * MAT(1,2) * MAT(3,1) +
|
||||
MAT(1,0) * MAT(0,1) * MAT(3,2) - MAT(1,0) * MAT(0,2) * MAT(3,1) -
|
||||
MAT(3,0) * MAT(0,1) * MAT(1,2) + MAT(3,0) * MAT(0,2) * MAT(1,1);
|
||||
|
||||
INV(3,3) = MAT(0,0) * MAT(1,1) * MAT(2,2) - MAT(0,0) * MAT(1,2) * MAT(2,1) -
|
||||
MAT(1,0) * MAT(0,1) * MAT(2,2) + MAT(1,0) * MAT(0,2) * MAT(2,1) +
|
||||
MAT(2,0) * MAT(0,1) * MAT(1,2) - MAT(2,0) * MAT(0,2) * MAT(1,1);
|
||||
|
||||
#undef MAT
|
||||
#undef INV
|
||||
|
||||
float det = m[0] * inv[0] + m[1] * inv[4] + m[2] * inv[8] + m[3] * inv[12];
|
||||
if (det == 0.0f) return Mat4::Identity();
|
||||
|
||||
float invDet = 1.0f / det;
|
||||
Mat4 result;
|
||||
for (int i = 0; i < 16; ++i)
|
||||
result.m[i] = inv[i] * invDet;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
25
src/core/types/rect.h
Normal file
25
src/core/types/rect.h
Normal file
@ -0,0 +1,25 @@
|
||||
// CE/types/rect.h
|
||||
#pragma once
|
||||
|
||||
#include "vec2.h"
|
||||
|
||||
namespace OX {
|
||||
|
||||
struct Rect
|
||||
{
|
||||
Vec2 pos{0, 0};
|
||||
Vec2 size{0, 0};
|
||||
|
||||
Rect() = default;
|
||||
Rect(const Vec2 &_pos, const Vec2 &_size)
|
||||
: pos(_pos), size(_size)
|
||||
{
|
||||
}
|
||||
|
||||
bool contains(const Vec2 &p) const
|
||||
{
|
||||
return p.x >= pos.x && p.y >= pos.y && p.x < pos.x + size.x && p.y < pos.y + size.y;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
155
src/core/types/vec2.h
Normal file
155
src/core/types/vec2.h
Normal file
@ -0,0 +1,155 @@
|
||||
#pragma once
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#include <ostream>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
namespace OX {
|
||||
|
||||
struct Vec2i;
|
||||
|
||||
struct Vec2
|
||||
{
|
||||
float x{0}, y{0};
|
||||
|
||||
Vec2() = default;
|
||||
Vec2(float x, float y) : x(x), y(y) {}
|
||||
Vec2(float v) : x(v), y(v) {}
|
||||
Vec2(const glm::vec2 &v) : x(v.x), y(v.y) {}
|
||||
Vec2(const Vec2i &v);
|
||||
|
||||
operator glm::vec2() const { return {x, y}; }
|
||||
|
||||
Vec2 operator+(const Vec2 &rhs) const { return {x + rhs.x, y + rhs.y}; }
|
||||
Vec2 operator-(const Vec2 &rhs) const { return {x - rhs.x, y - rhs.y}; }
|
||||
Vec2 operator*(float scalar) const { return {x * scalar, y * scalar}; }
|
||||
Vec2 operator/(float scalar) const { return {x / scalar, y / scalar}; }
|
||||
|
||||
Vec2 operator*(const Vec2 &rhs) const { return {x * rhs.x, y * rhs.y}; }
|
||||
|
||||
Vec2 &operator+=(const Vec2 &rhs)
|
||||
{
|
||||
x += rhs.x;
|
||||
y += rhs.y;
|
||||
return *this;
|
||||
}
|
||||
Vec2 &operator-=(const Vec2 &rhs)
|
||||
{
|
||||
x -= rhs.x;
|
||||
y -= rhs.y;
|
||||
return *this;
|
||||
}
|
||||
Vec2 &operator*=(float scalar)
|
||||
{
|
||||
x *= scalar;
|
||||
y *= scalar;
|
||||
return *this;
|
||||
}
|
||||
Vec2 &operator/=(float scalar)
|
||||
{
|
||||
x /= scalar;
|
||||
y /= scalar;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vec2 operator-() const { return {-x, -y}; }
|
||||
|
||||
bool operator==(const Vec2 &rhs) const { return x == rhs.x && y == rhs.y; }
|
||||
bool operator!=(const Vec2 &rhs) const { return !(*this == rhs); }
|
||||
|
||||
float Length() const { return std::sqrt(x * x + y * y); }
|
||||
float LengthSquared() const { return x * x + y * y; }
|
||||
|
||||
Vec2 Normalized() const
|
||||
{
|
||||
float len = Length();
|
||||
return len != 0 ? *this / len : Vec2(0.0f);
|
||||
}
|
||||
|
||||
void Normalize()
|
||||
{
|
||||
float len = Length();
|
||||
if (len != 0)
|
||||
{
|
||||
x /= len;
|
||||
y /= len;
|
||||
}
|
||||
}
|
||||
|
||||
float Dot(const Vec2 &rhs) const { return x * rhs.x + y * rhs.y; }
|
||||
|
||||
void Clamp(const Vec2 &min, const Vec2 &max)
|
||||
{
|
||||
x = std::max(min.x, std::min(x, max.x));
|
||||
y = std::max(min.y, std::min(y, max.y));
|
||||
}
|
||||
|
||||
static Vec2 Lerp(const Vec2 &a, const Vec2 &b, float t)
|
||||
{
|
||||
return a + (b - a) * t;
|
||||
}
|
||||
|
||||
static float Distance(const Vec2 &a, const Vec2 &b)
|
||||
{
|
||||
return (a - b).Length();
|
||||
}
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &os, const Vec2 &v)
|
||||
{
|
||||
return os << "(" << v.x << ", " << v.y << ")";
|
||||
}
|
||||
};
|
||||
|
||||
struct Vec2i
|
||||
{
|
||||
int x{0}, y{0};
|
||||
|
||||
Vec2i() = default;
|
||||
Vec2i(int x, int y) : x(x), y(y) {}
|
||||
Vec2i(int v) : x(v), y(v) {}
|
||||
Vec2i(const Vec2 &v) : x(static_cast<int>(v.x)), y(static_cast<int>(v.y)) {}
|
||||
|
||||
Vec2i operator+(const Vec2i &rhs) const { return {x + rhs.x, y + rhs.y}; }
|
||||
Vec2i operator-(const Vec2i &rhs) const { return {x - rhs.x, y - rhs.y}; }
|
||||
Vec2i operator*(int scalar) const { return {x * scalar, y * scalar}; }
|
||||
Vec2i operator/(int scalar) const { return {x / scalar, y / scalar}; }
|
||||
|
||||
Vec2 operator*(const Vec2 &rhs) const { return Vec2(x * rhs.x, y * rhs.y); }
|
||||
|
||||
Vec2i &operator+=(const Vec2i &rhs)
|
||||
{
|
||||
x += rhs.x;
|
||||
y += rhs.y;
|
||||
return *this;
|
||||
}
|
||||
Vec2i &operator-=(const Vec2i &rhs)
|
||||
{
|
||||
x -= rhs.x;
|
||||
y -= rhs.y;
|
||||
return *this;
|
||||
}
|
||||
Vec2i &operator*=(int scalar)
|
||||
{
|
||||
x *= scalar;
|
||||
y *= scalar;
|
||||
return *this;
|
||||
}
|
||||
Vec2i &operator/=(int scalar)
|
||||
{
|
||||
x /= scalar;
|
||||
y /= scalar;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const Vec2i &rhs) const { return x == rhs.x && y == rhs.y; }
|
||||
bool operator!=(const Vec2i &rhs) const { return !(*this == rhs); }
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &os, const Vec2i &v)
|
||||
{
|
||||
return os << "(" << v.x << ", " << v.y << ")";
|
||||
}
|
||||
};
|
||||
|
||||
inline Vec2 operator*(float scalar, const Vec2 &v) { return v * scalar; }
|
||||
|
||||
}
|
120
src/core/types/vec3.h
Normal file
120
src/core/types/vec3.h
Normal file
@ -0,0 +1,120 @@
|
||||
#pragma once
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#include <ostream>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
namespace OX {
|
||||
|
||||
struct Vec3
|
||||
{
|
||||
float x{0}, y{0}, z{0};
|
||||
|
||||
Vec3() = default;
|
||||
Vec3(const float x, const float y, const float z) : x(x), y(y), z(z) {}
|
||||
Vec3(const float v) : x(v), y(v), z(v) {}
|
||||
Vec3(const glm::vec3 &v) : x(v.x), y(v.y), z(v.z) {}
|
||||
|
||||
operator glm::vec3() const { return { x, y, z }; }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Vec3 operator+(const Vec3 &rhs) const { return {x + rhs.x, y + rhs.y, z + rhs.z}; }
|
||||
Vec3 operator-(const Vec3 &rhs) const { return {x - rhs.x, y - rhs.y, z - rhs.z}; }
|
||||
Vec3 operator*(const float scalar) const { return {x * scalar, y * scalar, z * scalar}; }
|
||||
Vec3 operator/(const float scalar) const { return {x / scalar, y / scalar, z / scalar}; }
|
||||
|
||||
Vec3 operator*(const Vec3 &rhs) const { return {x * rhs.x, y * rhs.y, z * rhs.z}; }
|
||||
|
||||
|
||||
|
||||
Vec3 &operator+=(const Vec3 &rhs) { x += rhs.x; y += rhs.y; z += rhs.z; return *this; }
|
||||
Vec3 &operator-=(const Vec3 &rhs) { x -= rhs.x; y -= rhs.y; z -= rhs.z; return *this; }
|
||||
Vec3 &operator*=(const float scalar) { x *= scalar; y *= scalar; z *= scalar; return *this; }
|
||||
Vec3 &operator/=(const float scalar) { x /= scalar; y /= scalar; z /= scalar; return *this; }
|
||||
|
||||
Vec3 operator-() const { return {-x, -y, -z}; }
|
||||
|
||||
bool operator==(const Vec3 &rhs) const { return x == rhs.x && y == rhs.y && z == rhs.z; }
|
||||
bool operator!=(const Vec3 &rhs) const { return !(*this == rhs); }
|
||||
|
||||
float Length() const { return std::sqrt(x * x + y * y + z * z); }
|
||||
float LengthSquared() const { return x * x + y * y + z * z; }
|
||||
|
||||
Vec3 Normalized() const
|
||||
{
|
||||
const float len = Length();
|
||||
return len != 0 ? *this / len : Vec3(0.0f);
|
||||
}
|
||||
|
||||
void Normalize()
|
||||
{
|
||||
if (const float len = Length(); len != 0)
|
||||
{
|
||||
x /= len;
|
||||
y /= len;
|
||||
z /= len;
|
||||
}
|
||||
}
|
||||
|
||||
float Dot(const Vec3 &rhs) const { return x * rhs.x + y * rhs.y + z * rhs.z; }
|
||||
|
||||
Vec3 Cross(const Vec3 &rhs) const
|
||||
{
|
||||
return Vec3(
|
||||
y * rhs.z - z * rhs.y,
|
||||
z * rhs.x - x * rhs.z,
|
||||
x * rhs.y - y * rhs.x
|
||||
);
|
||||
}
|
||||
|
||||
void Clamp(const Vec3 &min, const Vec3 &max)
|
||||
{
|
||||
x = std::max(min.x, std::min(x, max.x));
|
||||
y = std::max(min.y, std::min(y, max.y));
|
||||
z = std::max(min.z, std::min(z, max.z));
|
||||
}
|
||||
|
||||
static Vec3 Lerp(const Vec3 &a, const Vec3 &b, const float t)
|
||||
{
|
||||
return a + (b - a) * t;
|
||||
}
|
||||
|
||||
static float Distance(const Vec3 &a, const Vec3 &b)
|
||||
{
|
||||
return (a - b).Length();
|
||||
}
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &os, const Vec3 &v)
|
||||
{
|
||||
return os << "(" << v.x << ", " << v.y << ", " << v.z << ")";
|
||||
}
|
||||
|
||||
float& operator[](const int i) {
|
||||
switch (i) {
|
||||
case 0: return x;
|
||||
case 1: return y;
|
||||
case 2: return z;
|
||||
default: throw std::out_of_range("Vec3 index out of range");
|
||||
}
|
||||
}
|
||||
|
||||
const float& operator[](const int i) const {
|
||||
switch (i) {
|
||||
case 0: return x;
|
||||
case 1: return y;
|
||||
case 2: return z;
|
||||
default: throw std::out_of_range("Vec3 index out of range");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
inline Vec3 operator*(const float scalar, const Vec3 &v) { return v * scalar; }
|
||||
|
||||
|
||||
|
||||
}
|
54
src/core/types/vec4.h
Normal file
54
src/core/types/vec4.h
Normal file
@ -0,0 +1,54 @@
|
||||
#pragma once
|
||||
|
||||
namespace OX {
|
||||
|
||||
struct Vec4
|
||||
{
|
||||
float x{0}, y{0}, z{0}, w{0};
|
||||
|
||||
Vec4() = default;
|
||||
Vec4(float _x, float _y, float _z, float _w)
|
||||
: x(_x), y(_y), z(_z), w(_w)
|
||||
{
|
||||
}
|
||||
|
||||
Vec4 &operator+=(const Vec4 &o)
|
||||
{
|
||||
x += o.x;
|
||||
y += o.y;
|
||||
z += o.z;
|
||||
w += o.w;
|
||||
return *this;
|
||||
}
|
||||
Vec4 &operator-=(const Vec4 &o)
|
||||
{
|
||||
x -= o.x;
|
||||
y -= o.y;
|
||||
z -= o.z;
|
||||
w -= o.w;
|
||||
return *this;
|
||||
}
|
||||
Vec4 &operator*=(float s)
|
||||
{
|
||||
x *= s;
|
||||
y *= s;
|
||||
z *= s;
|
||||
w *= s;
|
||||
return *this;
|
||||
}
|
||||
Vec4 &operator/=(float s)
|
||||
{
|
||||
x /= s;
|
||||
y /= s;
|
||||
z /= s;
|
||||
w /= s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend Vec4 operator+(Vec4 a, const Vec4 &b) { return a += b; }
|
||||
friend Vec4 operator-(Vec4 a, const Vec4 &b) { return a -= b; }
|
||||
friend Vec4 operator*(Vec4 v, float s) { return v *= s; }
|
||||
friend Vec4 operator/(Vec4 v, float s) { return v /= s; }
|
||||
};
|
||||
|
||||
}
|
@ -8,6 +8,8 @@
|
||||
#include <imgui_impl_opengl3.h>
|
||||
#include <imgui_impl_glfw.h>
|
||||
#include "Windows/LoggerWindow.h"
|
||||
|
||||
|
||||
namespace OX {
|
||||
|
||||
void Editor::Init(Core& core)
|
||||
|
@ -21,16 +21,6 @@ namespace OX::LoggerWindow {
|
||||
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)
|
||||
{
|
||||
@ -80,6 +70,7 @@ namespace OX::LoggerWindow {
|
||||
(level == MessageType::Info && s_ShowInfo) ||
|
||||
(level == MessageType::Warning && s_ShowWarning) ||
|
||||
(level == MessageType::Error && s_ShowError) ||
|
||||
(level == MessageType::Verbose && s_ShowVerbose) ||
|
||||
(level == MessageType::Debug && s_ShowDebug);
|
||||
|
||||
if (!show)
|
||||
@ -98,7 +89,9 @@ namespace OX::LoggerWindow {
|
||||
ImGui::TableNextRow();
|
||||
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
ImVec4 col = GetColor(level);
|
||||
const Color color = Logger::GetRGBColor(level);
|
||||
ImVec4 col(color.r, color.g, color.b, color.a);
|
||||
|
||||
const ImVec2 cursor = ImGui::GetCursorScreenPos();
|
||||
constexpr float barWidth = 4.0f;
|
||||
const float textHeight = ImGui::GetTextLineHeight();
|
||||
|
Loading…
Reference in New Issue
Block a user