Skip to content
Snippets Groups Projects
Commit 7b87ce6b authored by Armin Co's avatar Armin Co
Browse files

QPong_v1.0

parent 8fadbfa9
No related branches found
No related tags found
No related merge requests found
Showing with 1019 additions and 0 deletions
build
.vscode
imgui.ini
[submodule "libs/spdlog"]
path = libs/spdlog
url = https://github.com/gabime/spdlog/
[submodule "libs/imgui"]
path = libs/imgui
url = https://github.com/ocornut/imgui
cmake_minimum_required(VERSION 3.10)
project(QPong VERSION 0.0.1 LANGUAGES C CXX)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_BUILD_TYPE Release)
set(CMAKE_CXX_FLAGS "-O3")
option(LOG_DEBUG_INFO "Enable logging t console" OFF)
if(LOG_DEBUG_INFO)
add_compile_definitions(ENABLE_LOG_DEBUG_INFO)
endif(LOG_DEBUG_INFO)
# Check for PkgConfig
find_package(PkgConfig REQUIRED)
# GUI/Window
add_subdirectory(GuiCore)
# QPong App sources
add_subdirectory(QPongApp)
# Libraries the project depends on:
add_subdirectory(libs/spdlog)
/// @file Application.cpp
/// @author Armin Co
///
#include <GLFW/glfw3.h>
#include "Application.hpp"
#include "Log.hpp"
#include "ApplicationEvent.hpp"
namespace GuiCore
{
Application* Application::s_instance = nullptr;
Application::Application(const std::string &name, uint32_t width, uint32_t height)
{
if (s_instance == nullptr)
{
Log::setup();
}
s_instance = this;
m_window = std::unique_ptr<IWindow>(IWindow::create({name, width, height}));
m_window->setEventCallback([this](auto &&... args) -> decltype(auto) { return this->onEvent(std::forward<decltype(args)>(args)...); });
m_guiLayer = std::make_shared<ImGuiLayer>();
pushLayer(m_guiLayer);
}
void Application::pushLayer(std::shared_ptr<Layer> layer)
{
m_layerStack.pushLayer(layer);
}
void Application::popLayer(std::shared_ptr<Layer> layer)
{
m_layerStack.popLayer(layer);
}
void Application::onEvent(Event &event)
{
Log::get()->trace("{}", event.toString());
EventDispatcher dispatcher(event);
dispatcher.dispatch<WindowCloseEvent>(
[this](auto &&... args) -> decltype(auto) { return this->onWindowClose(std::forward<decltype(args)>(args)...); });
dispatcher.dispatch<WindowResizeEvent>(
[this](auto &&... args) -> decltype(auto) { return this->onWindowResize(std::forward<decltype(args)>(args)...); });
for (auto it = m_layerStack.rbegin(); it != m_layerStack.rend(); ++it)
{
if (event.handled)
{
break;
}
(*it)->onEvent(event);
}
}
void Application::run()
{
while (m_isRunnig)
{
float time = static_cast<float>(glfwGetTime());
Timestep timeStep = time - m_lastFrameTime;
m_lastFrameTime = time;
if (!m_minimzed)
{
for (auto layer : m_layerStack)
{
layer->onUpdate(timeStep);
}
}
m_guiLayer->begin();
for (auto layer: m_layerStack)
{
layer->onGuiRender();
}
m_guiLayer->end();
m_window->onUpdate();
}
}
bool Application::onWindowClose(Event &event)
{
m_isRunnig = false;
return true;
}
bool Application::onWindowResize(Event &event)
{
WindowResizeEvent *rsEvent = static_cast<WindowResizeEvent*>(&event);
Log::get()->trace("Window minimized, {0}, {1}", rsEvent->getWidth(), rsEvent->getHeight());
glViewport(0,0, rsEvent->getWidth(), rsEvent->getHeight());
return false;
}
Application& Application::get()
{
return *s_instance;
}
IWindow& Application::getWindow()
{
return *m_window;
}
}
/// @file Application.hpp
/// @author Armin Co
///
#ifndef GUI_CORE_APPLICATION_HPP
#define GUI_CORE_APPLICATION_HPP
#include <string>
#include <memory>
#include "Event.hpp"
#include "IWindow.hpp"
#include "LayerStack.hpp"
#include "ImGuiLayer.hpp"
#include "ApplicationEvent.hpp"
namespace GuiCore
{
class Application
{
public:
Application(const std::string &name = "Application", uint32_t width = 1280, uint32_t height = 720);
virtual ~Application() {}
void run();
void onEvent(Event &e);
void pushLayer(std::shared_ptr<Layer> layer);
void popLayer(std::shared_ptr<Layer> layer);
IWindow& getWindow();
bool onWindowClose(Event &e);
bool onWindowResize(Event &e);
static Application& get();
private:
std::unique_ptr<IWindow> m_window;
bool m_isRunnig = true;
bool m_minimzed = false;
LayerStack m_layerStack;
float m_lastFrameTime = 0.0f;
std::shared_ptr<ImGuiLayer> m_guiLayer;
static Application *s_instance;
};
}
#endif
\ No newline at end of file
/// @file ApplicationEvent.hpp
/// @author Armin Co
///
#ifndef APPLICATION_EVENT_HPP
#define APPLICATION_EVENT_HPP
#include <sstream>
#include "Event.hpp"
namespace GuiCore
{
class WindowResizeEvent : public Event
{
public:
WindowResizeEvent(uint32_t width, uint32_t height)
: m_width{width}
, m_height{height}
{
}
uint32_t getWidth() const {return m_width;}
uint32_t getHeight() const {return m_height;}
std::string toString() const override
{
std::stringstream ss;
ss << "WindowResizeEvent: " << m_width << ", " << m_height;
return ss.str();
}
EVENT_CLASS_TYPE(WindowResize)
EVENT_CLASS_CATEGORY(EventCategoryApplication)
private:
uint32_t m_width;
uint32_t m_height;
};
class WindowCloseEvent : public Event
{
public:
WindowCloseEvent() = default;
EVENT_CLASS_TYPE(WindowClose)
EVENT_CLASS_CATEGORY(EventCategoryApplication)
};
}
#endif
\ No newline at end of file
find_package( Freetype REQUIRED)
# GuiCore library
add_library(GuiCore
Application.cpp
Input.cpp
Layer.cpp
LayerStack.cpp
Log.cpp
Timer.cpp
Timestep.cpp
Glyphs.cpp
)
target_include_directories( GuiCore PUBLIC
../libs/spdlog/include/
${FREETYPE_INCLUDE_DIRS}
)
target_link_libraries( GuiCore
spdlog
${FREETYPE_LIBRARIES}
)
add_compile_definitions(IMGUI_IMPL_OPENGL_LOADER_GL3W)
# ImGui is a dependency of GuiCore
add_library( ImGui
Shader.cpp
ImGuiLayer.cpp
../libs/imgui/imgui.cpp
../libs/imgui/imgui_draw.cpp
../libs/imgui/imgui_widgets.cpp
../libs/imgui/imgui_tables.cpp
../libs/imgui/backends/imgui_impl_glfw.cpp
../libs/imgui/backends/imgui_impl_opengl3.cpp
../libs/imgui/examples/libs/gl3w/GL/gl3w.c
)
target_include_directories( ImGui PUBLIC
../libs
../libs/imgui # for glfw
../libs/imgui/backends
../libs/imgui/examples/libs/gl3w
../libs/spdlog/include
)
target_link_libraries( GuiCore
ImGui
)
# Check for GLFW3 and link
pkg_check_modules(GLFW glfw3)
target_include_directories(GuiCore PUBLIC ${GLFW_INCLUDE_DIRS})
target_link_libraries(GuiCore ${GLFW_LIBRARIES})
# Check for OpenGL
set(OpenGL_GL_PREFERENCE GLVND)
find_package(OpenGL REQUIRED)
target_link_libraries(GuiCore OpenGL::GL ${CMAKE_DL_LIBS})
/// @file Event.hpp
/// @author Armin Co
///
#ifndef GUI_CORE_EVENT_HPP
#define GUI_CORE_EVENT_HPP
#include <string>
#include "Log.hpp"
#define BIT(x) (1 << x)
namespace GuiCore
{
enum class EventType
{
None = 0,
WindowClose, WindowResize, WindowFocus, WindowLostFocus, WindowMoved,
AppTick, AppUpdate, AppRender,
KeyPressed, KeyReleased, KeyTyped,
MouseButtonPressed, MouseButtonReleased, MouseMoved, MouseScrolled
};
enum EventCategory
{
None = 0,
EventCategoryApplication = BIT(0),
EventCategoryInput = BIT(1),
EventCategoryKeyboard = BIT(2),
EventCategoryMouse = BIT(3),
EventCategoryMouseButton = BIT(4)
};
#define EVENT_CLASS_TYPE(type) static EventType getStaticType() { return EventType::type; }\
virtual EventType getEventType() const override { return getStaticType(); }\
virtual const char* getName() const override { return #type; }
#define EVENT_CLASS_CATEGORY(category) virtual int getCategoryFlags() const override { return category; }
class Event
{
public:
bool handled = false;
virtual EventType getEventType() const = 0;
virtual const char * getName() const = 0;
virtual int getCategoryFlags() const = 0;
virtual std::string toString() const {return getName();}
inline bool isInCategory(EventCategory category)
{
return getCategoryFlags() & category;
}
};
class EventDispatcher
{
public:
EventDispatcher(Event &event)
: m_event{event}
{
}
template<typename T, typename F>
bool dispatch(const F& function)
{
if (m_event.getEventType() == T::getStaticType())
{
m_event.handled = function(static_cast<T&>(m_event));
return true;
}
return false;
}
private:
Event &m_event;
};
inline std::ostream& operator<<(std::ostream& os, const Event &e)
{
return os << e.toString();
}
}
#endif
\ No newline at end of file
/// @file Glyphs.cpp
/// @author Armin Co
///
#include "Glyphs.hpp"
#include <GLFW/glfw3.h>
#include "Log.hpp"
#include <glm/gtc/type_ptr.hpp>
extern "C" {
#include <ft2build.h>
#include FT_FREETYPE_H
}
std::map<char, GuiCore::Character> GuiCore::Glyphs::s_characters;
GuiCore::Shader* GuiCore::Glyphs::m_shader;
GLuint GuiCore::Glyphs::m_vertexArray;
GLuint GuiCore::Glyphs::m_vertexBuffer;
glm::mat4 GuiCore::Glyphs::projection = glm::ortho(-3.2f, 3.2f, -1.8f, 1.8f, -1.0f, 1.0f);
void GuiCore::Glyphs::setup()
{
m_shader = GuiCore::Shader::fromGLSLTextFiles(
"assets/shaders/glyph.vert.glsl",
"assets/shaders/glyph.frag.glsl"
);
glGenVertexArrays(1, &m_vertexArray);
glGenBuffers(1, &m_vertexBuffer);
glBindVertexArray(m_vertexArray);
glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 6 * 4, NULL, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
FT_Library ft;
if (FT_Init_FreeType(&ft))
{
GuiCore::Log::get()->error("ERROR::FREETYPE: Could not init FreeType Library");
}
FT_Face face;
if (FT_New_Face(ft, "assets/Font.ttf", 0, &face))
{
GuiCore::Log::get()->error("ERROR::FREETYPE: Failed to load font");
}
FT_Set_Pixel_Sizes(face, 0, 48);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
for (unsigned char c = 0; c < 128; c++)
{
// load character glyph
auto error = FT_Load_Char(face, c, FT_LOAD_RENDER);
if (error)
{
GuiCore::Log::get()->error("ERROR::FREETYTPE: Failed to load Glyph {0} {1}", c, error);
continue;
}
// generate texture
unsigned int texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RED,
face->glyph->bitmap.width,
face->glyph->bitmap.rows,
0,
GL_RED,
GL_UNSIGNED_BYTE,
face->glyph->bitmap.buffer
);
// set texture options
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// now store character for later use
Character character = {
texture,
glm::ivec2(face->glyph->bitmap.width, face->glyph->bitmap.rows),
glm::ivec2(face->glyph->bitmap_left, face->glyph->bitmap_top),
static_cast<uint32_t>(face->glyph->advance.x)
};
s_characters.insert(std::pair<char, Character>(c, character));
}
}
void GuiCore::Glyphs::renderText(std::string text, float x, float y, float scale, glm::vec3 color)
{
glUseProgram(m_shader->getRendererID());
glUniformMatrix4fv(glGetUniformLocation(m_shader->getRendererID(), "projection"), 1, GL_FALSE, glm::value_ptr(projection));
glUniform3f(glGetUniformLocation(m_shader->getRendererID(), "textColor"), color.r, color.g, color.b);
glActiveTexture(GL_TEXTURE0);
glBindVertexArray(m_vertexArray);
std::string::const_iterator c;
for (c = text.begin(); c != text.end(); c++)
{
Character ch = s_characters[*c];
float xPos = x + ch.bearing.x * scale;
float yPos = y - (ch.size.y - ch.bearing.y) * scale;
float w = ch.size.x * scale;
float h = ch.size.y * scale;
float vertices[6][4] = {
{ xPos, yPos + h, 0.0f, 0.0f },
{ xPos, yPos, 0.0f, 1.0f },
{ xPos + w, yPos, 1.0f, 1.0f },
{ xPos, yPos + h, 0.0f, 0.0f },
{ xPos + w, yPos, 1.0f, 1.0f },
{ xPos + w, yPos + h, 1.0f, 0.0f }
};
glBindTexture(GL_TEXTURE_2D, ch.textureId);
glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDrawArrays(GL_TRIANGLES, 0, 6);
x += (ch.advance >> 6) * scale;
}
glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D, 0);
}
\ No newline at end of file
/// @file Glyphs.hpp
/// @author Armin Co
///
#ifndef GUI_CORE_GLYPHS_HPP
#define GUI_CORE_GLYPHS_HPP
#include <map>
#include <glm/glm.hpp>
#include "Shader.hpp"
namespace GuiCore
{
struct Character {
unsigned int textureId; // ID handle of the glyph texture
glm::ivec2 size; // Size of glyph
glm::ivec2 bearing; // Offset from baseline to left/top of glyph
unsigned int advance; // Offset to advance to next glyph
};
class Glyphs
{
public:
static void setup();
static void renderText(std::string text, float x, float y, float scale, glm::vec3 color);
private:
static std::map<char, Character> s_characters;
static Shader *m_shader;
static GLuint m_vertexArray;
static GLuint m_vertexBuffer;
static glm::mat4 projection;
};
}
#endif
\ No newline at end of file
/// @file IWindow.hpp
/// @author Armin Co
///
#ifndef GUI_CORE_WINDOW_HPP
#define GUI_CORE_WINDOW_HPP
#include <string>
#include <functional>
#include "Event.hpp"
namespace GuiCore
{
struct WindowProperties
{
std::string title;
uint32_t width;
uint32_t height;
WindowProperties(const std::string &t = "Application", uint32_t w = 1920, uint32_t h = 1080)
: title{t}
, width{w}
, height{h}
{
}
};
class IWindow
{
public:
virtual ~IWindow() {}
virtual void onUpdate() = 0;
virtual uint32_t getWidth() const = 0;
virtual uint32_t getHeight() const = 0;
virtual void setEventCallback(const std::function<void(GuiCore::Event&)>) = 0;
virtual void setVSync(bool enabled) = 0;
virtual bool isVSyncEnabled() const = 0;
virtual void* getNativeWindow() const = 0;
static IWindow* create(const WindowProperties &props = WindowProperties());
};
}
#endif
\ No newline at end of file
/// @file ImGuiLayer.cpp
/// @author Armin Co
///
#include <GLFW/glfw3.h>
#include <imgui/imgui.h>
#include <imgui/backends/imgui_impl_glfw.h>
#include <imgui/backends/imgui_impl_opengl3.h>
#include "Application.hpp"
#include "ImGuiLayer.hpp"
#include "Log.hpp"
using namespace GuiCore;
ImGuiLayer::ImGuiLayer()
: Layer("ImGuiLayer")
{
}
ImGuiLayer::~ImGuiLayer()
{
}
void ImGuiLayer::onAttach()
{
GuiCore::Log::get()->trace("onAttach ImGuiLayer");
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
ImGui::StyleColorsDark();
Application& app = Application::get();
GLFWwindow *window = static_cast<GLFWwindow*>(app.getWindow().getNativeWindow());
ImGui_ImplGlfw_InitForOpenGL(window, true);
ImGui_ImplOpenGL3_Init("#version 330");
}
void ImGuiLayer::onDetach()
{
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
}
void ImGuiLayer::begin()
{
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
}
void ImGuiLayer::end()
{
ImGuiIO& io = ImGui::GetIO();
Application& app = Application::get();
io.DisplaySize = ImVec2((float)app.getWindow().getWidth(), (float)app.getWindow().getHeight());
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
}
void ImGuiLayer::onEvent(Event &event)
{
}
bool ImGuiLayer::onMouseButtonPressed(Event &event)
{
return false;
}
/// @file ImGuiLayer.hpp
/// @author Armin Co
///
#ifndef IM_GUI_LAYER_HPP
#define IM_GUI_LAYER_HPP
#include "Layer.hpp"
#include "Event.hpp"
namespace GuiCore
{
class ImGuiLayer : public Layer
{
public:
ImGuiLayer();
virtual ~ImGuiLayer();
virtual void onAttach() override;
virtual void onDetach() override;
void begin();
void end();
virtual void onEvent(Event &event);
bool onMouseButtonPressed(Event &event);
private:
float m_time = 0.0f;
};
}
#endif
\ No newline at end of file
/// @file Input.cpp
/// @author Armin Co
///
#include "Input.hpp"
#include "Application.hpp"
#include <GLFW/glfw3.h>
namespace GuiCore
{
Input* Input::s_instance = new Input();
bool Input::isKeyPressed(int keyCode)
{
auto window = static_cast<GLFWwindow*>(Application::get().getWindow().getNativeWindow());
auto state = glfwGetKey(window, keyCode);
return state == GLFW_PRESS || state == GLFW_REPEAT;
}
bool Input::isMouseButtonPressed(int button)
{
auto window = static_cast<GLFWwindow*>(Application::get().getWindow().getNativeWindow());
auto state = glfwGetMouseButton(window, button);
return state == GLFW_PRESS;
}
std::pair<float, float> Input::getMousePosition()
{
auto window = static_cast<GLFWwindow*>(Application::get().getWindow().getNativeWindow());
double xPos {0};
double yPos {0};
glfwGetCursorPos(window, &xPos, &yPos);
return {static_cast<float>(xPos), static_cast<float>(yPos)};
}
float Input::getMouseX()
{
auto[x, y] = getMousePosition();
return x;
}
float Input::getMouseY()
{
auto[x, y] = getMousePosition();
return y;
}
}
\ No newline at end of file
/// @file Input.hpp
/// @author Armin Co
///
#ifndef GUI_CORE_INPUT_HPP
#define GUI_CORE_INPUT_HPP
#include <utility>
namespace GuiCore
{
class Input
{
protected:
Input() = default;
public:
Input(const Input &) = delete;
Input& operator=(const Input&) = delete;
static bool isKeyPressed(int keyCode);
static bool isMouseButtonPressed(int button);
static std::pair<float, float> getMousePosition();
static float getMouseX();
static float getMouseY();
private:
static Input* s_instance;
};
}
namespace Key
{
constexpr int A {65};
constexpr int B {66};
constexpr int C {67};
constexpr int D {68};
constexpr int E {69};
constexpr int F {70};
constexpr int G {71};
constexpr int H {72};
constexpr int I {73};
constexpr int J {74};
constexpr int K {75};
constexpr int L {76};
constexpr int M {77};
constexpr int N {78};
constexpr int O {79};
constexpr int P {80};
constexpr int Q {81};
constexpr int R {82};
constexpr int S {83};
constexpr int T {84};
constexpr int U {85};
constexpr int V {86};
constexpr int W {87};
constexpr int X {88};
constexpr int Z {89};
constexpr int Y {90};
constexpr int Right {262};
constexpr int Left {263};
constexpr int Down {264};
constexpr int Up {265};
}
#endif
\ No newline at end of file
/// @file Layer.cpp
/// @author Armin Co
///
#include "Layer.hpp"
namespace GuiCore
{
Layer::Layer(const std::string &debugName)
: m_debugName{debugName}
{
}
Layer::~Layer()
{
}
const std::string &Layer::getName() const
{
return m_debugName;
}
}
/// @file Layer.hpp
/// @author Armin Co
///
#ifndef GUI_CORE_LAYER_HPP
#define GUI_CORE_LAYER_HPP
#include <string>
#include "Event.hpp"
#include "Timestep.hpp"
namespace GuiCore
{
class Layer
{
public:
Layer(const std::string &name = "Layer");
virtual ~Layer();
virtual void onAttach() {}
virtual void onDetach() {}
virtual void onUpdate(Timestep ts) {}
virtual void onGuiRender() {}
virtual void onEvent(Event &event){}
const std::string &getName() const;
protected:
std::string m_debugName;
};
}
#endif
\ No newline at end of file
/// @file LayerStack.cpp
/// @author Armin Co
///
#include <algorithm>
#include "LayerStack.hpp"
namespace GuiCore
{
LayerStack::LayerStack()
{
}
LayerStack::~LayerStack()
{
for (auto layer : m_layers)
{
layer->~Layer();
}
}
void LayerStack::pushLayer(std::shared_ptr<Layer> layer)
{
m_layers.emplace(lastLayer(), layer);
++m_layerIndex;
layer->onAttach();
}
void LayerStack::popLayer(std::shared_ptr<Layer> layer)
{
auto it = std::find(firstLayer(), lastLayer(), layer);
if (it != lastLayer())
{
layer->onDetach();
m_layers.erase(it);
--m_layerIndex;
}
}
Layers::iterator LayerStack::begin()
{
return m_layers.begin();
}
Layers::iterator LayerStack::end()
{
return m_layers.end();
}
Layers::iterator LayerStack::firstLayer()
{
return m_layers.begin();
}
Layers::iterator LayerStack::lastLayer()
{
return m_layers.begin() + m_layerIndex;
}
Layers::reverse_iterator LayerStack::rbegin()
{
return m_layers.rbegin();
}
Layers::reverse_iterator LayerStack::rend()
{
return m_layers.rend();
}
}
/// @file LayerStack.hpp
/// @author Armin Co
///
#ifndef GUI_CORE_LAYERSTACK_HPP
#define GUI_CORE_LAYERSTACK_HPP
#include <vector>
#include <memory>
#include "Layer.hpp"
namespace GuiCore
{
using Layers = std::vector<std::shared_ptr<Layer>>;
class LayerStack
{
public:
LayerStack();
~LayerStack();
void pushLayer(std::shared_ptr<Layer> layer);
void popLayer(std::shared_ptr<Layer> layer);
Layers::iterator begin();
Layers::iterator end();
Layers::reverse_iterator rbegin();
Layers::reverse_iterator rend();
private:
Layers::iterator firstLayer();
Layers::iterator lastLayer();
Layers m_layers;
uint32_t m_layerIndex{0};
};
}
#endif
\ No newline at end of file
/// @file Log.cpp
/// @author Armin Co
///
#include "spdlog/sinks/stdout_color_sinks.h"
#include "Log.hpp"
namespace GuiCore
{
std::shared_ptr<spdlog::logger> Log::s_logger;
void Log::setup()
{
spdlog::set_pattern("%^[%T] %n: %v%$");
s_logger = spdlog::stdout_color_mt("GuiCore");
#ifdef ENABLE_LOG_DEBUG_INFO
s_logger->set_level(spdlog::level::trace);
#else
s_logger->set_level(spdlog::level::info);
#endif
}
std::shared_ptr<spdlog::logger> Log::get()
{
return s_logger;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment