Uhhh changes idek anymore mayn

This commit is contained in:
NaifBanana 2025-11-05 00:21:11 -06:00
parent ac1762cb67
commit a7428ef55f
19 changed files with 553 additions and 10286 deletions

4
.gitignore vendored
View File

@ -1,2 +1,4 @@
build/
.vscode/
.vscode/
CMakeFiles/
CMakeCache.txt

View File

@ -1,20 +1,27 @@
cmake_minimum_required(VERSION 3.10)
project(NBEngine VERSION 0.1.0 LANGUAGES C CXX)
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
include(CPack)
if(CMAKE_BUILD_TYPE STREQUAL "Release")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ./release)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ./release)
endif()
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ./debug)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ./debug)
add_compile_definitions(_NB_GL_DEBUG_ON)
endif()
include_directories(./dep ./include)
link_directories(../glfw-3.3.9/build/src)
find_package(OpenGL)
add_subdirectory(../glfw ../glfw/build)
include_directories(./dep ./include ../glfw/include ../glad/include)
set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
add_library(NBWindow ./src/Window.cpp)
add_library(NBEvents ./src/Events.cpp)
add_library(NBEvents ./src/NBEvents/Events.cpp)
add_library(NBCore ./src/NBCoreUtils/Errors.cpp)
find_package(OpenGL REQUIRED)
add_subdirectory(./src/NBWindow ./NBWindows)
add_subdirectory(./tests ./tests)

File diff suppressed because it is too large Load Diff

View File

@ -1,634 +0,0 @@
/*************************************************************************
* GLFW 3.3 - www.glfw.org
* A library for OpenGL, window and input
*------------------------------------------------------------------------
* Copyright (c) 2002-2006 Marcus Geelnard
* Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would
* be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not
* be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*
*************************************************************************/
#ifndef _glfw3_native_h_
#define _glfw3_native_h_
#ifdef __cplusplus
extern "C" {
#endif
/*************************************************************************
* Doxygen documentation
*************************************************************************/
/*! @file glfw3native.h
* @brief The header of the native access functions.
*
* This is the header file of the native access functions. See @ref native for
* more information.
*/
/*! @defgroup native Native access
* @brief Functions related to accessing native handles.
*
* **By using the native access functions you assert that you know what you're
* doing and how to fix problems caused by using them. If you don't, you
* shouldn't be using them.**
*
* Before the inclusion of @ref glfw3native.h, you may define zero or more
* window system API macro and zero or more context creation API macros.
*
* The chosen backends must match those the library was compiled for. Failure
* to do this will cause a link-time error.
*
* The available window API macros are:
* * `GLFW_EXPOSE_NATIVE_WIN32`
* * `GLFW_EXPOSE_NATIVE_COCOA`
* * `GLFW_EXPOSE_NATIVE_X11`
* * `GLFW_EXPOSE_NATIVE_WAYLAND`
*
* The available context API macros are:
* * `GLFW_EXPOSE_NATIVE_WGL`
* * `GLFW_EXPOSE_NATIVE_NSGL`
* * `GLFW_EXPOSE_NATIVE_GLX`
* * `GLFW_EXPOSE_NATIVE_EGL`
* * `GLFW_EXPOSE_NATIVE_OSMESA`
*
* These macros select which of the native access functions that are declared
* and which platform-specific headers to include. It is then up your (by
* definition platform-specific) code to handle which of these should be
* defined.
*
* If you do not want the platform-specific headers to be included, define
* `GLFW_NATIVE_INCLUDE_NONE` before including the @ref glfw3native.h header.
*
* @code
* #define GLFW_EXPOSE_NATIVE_WIN32
* #define GLFW_EXPOSE_NATIVE_WGL
* #define GLFW_NATIVE_INCLUDE_NONE
* #include <GLFW/glfw3native.h>
* @endcode
*/
/*************************************************************************
* System headers and types
*************************************************************************/
#if !defined(GLFW_NATIVE_INCLUDE_NONE)
#if defined(GLFW_EXPOSE_NATIVE_WIN32) || defined(GLFW_EXPOSE_NATIVE_WGL)
/* This is a workaround for the fact that glfw3.h needs to export APIENTRY (for
* example to allow applications to correctly declare a GL_KHR_debug callback)
* but windows.h assumes no one will define APIENTRY before it does
*/
#if defined(GLFW_APIENTRY_DEFINED)
#undef APIENTRY
#undef GLFW_APIENTRY_DEFINED
#endif
#include <windows.h>
#endif
#if defined(GLFW_EXPOSE_NATIVE_COCOA) || defined(GLFW_EXPOSE_NATIVE_NSGL)
#if defined(__OBJC__)
#import <Cocoa/Cocoa.h>
#else
#include <ApplicationServices/ApplicationServices.h>
#include <objc/objc.h>
#endif
#endif
#if defined(GLFW_EXPOSE_NATIVE_X11) || defined(GLFW_EXPOSE_NATIVE_GLX)
#include <X11/Xlib.h>
#include <X11/extensions/Xrandr.h>
#endif
#if defined(GLFW_EXPOSE_NATIVE_WAYLAND)
#include <wayland-client.h>
#endif
#if defined(GLFW_EXPOSE_NATIVE_WGL)
/* WGL is declared by windows.h */
#endif
#if defined(GLFW_EXPOSE_NATIVE_NSGL)
/* NSGL is declared by Cocoa.h */
#endif
#if defined(GLFW_EXPOSE_NATIVE_GLX)
/* This is a workaround for the fact that glfw3.h defines GLAPIENTRY because by
* default it also acts as an OpenGL header
* However, glx.h will include gl.h, which will define it unconditionally
*/
#if defined(GLFW_GLAPIENTRY_DEFINED)
#undef GLAPIENTRY
#undef GLFW_GLAPIENTRY_DEFINED
#endif
#include <GL/glx.h>
#endif
#if defined(GLFW_EXPOSE_NATIVE_EGL)
#include <EGL/egl.h>
#endif
#if defined(GLFW_EXPOSE_NATIVE_OSMESA)
/* This is a workaround for the fact that glfw3.h defines GLAPIENTRY because by
* default it also acts as an OpenGL header
* However, osmesa.h will include gl.h, which will define it unconditionally
*/
#if defined(GLFW_GLAPIENTRY_DEFINED)
#undef GLAPIENTRY
#undef GLFW_GLAPIENTRY_DEFINED
#endif
#include <GL/osmesa.h>
#endif
#endif /*GLFW_NATIVE_INCLUDE_NONE*/
/*************************************************************************
* Functions
*************************************************************************/
#if defined(GLFW_EXPOSE_NATIVE_WIN32)
/*! @brief Returns the adapter device name of the specified monitor.
*
* @return The UTF-8 encoded adapter device name (for example `\\.\DISPLAY1`)
* of the specified monitor, or `NULL` if an [error](@ref error_handling)
* occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.1.
*
* @ingroup native
*/
GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* monitor);
/*! @brief Returns the display device name of the specified monitor.
*
* @return The UTF-8 encoded display device name (for example
* `\\.\DISPLAY1\Monitor0`) of the specified monitor, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.1.
*
* @ingroup native
*/
GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* monitor);
/*! @brief Returns the `HWND` of the specified window.
*
* @return The `HWND` of the specified window, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @remark The `HDC` associated with the window can be queried with the
* [GetDC](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdc)
* function.
* @code
* HDC dc = GetDC(glfwGetWin32Window(window));
* @endcode
* This DC is private and does not need to be released.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window);
#endif
#if defined(GLFW_EXPOSE_NATIVE_WGL)
/*! @brief Returns the `HGLRC` of the specified window.
*
* @return The `HGLRC` of the specified window, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref
* GLFW_NOT_INITIALIZED.
*
* @remark The `HDC` associated with the window can be queried with the
* [GetDC](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdc)
* function.
* @code
* HDC dc = GetDC(glfwGetWin32Window(window));
* @endcode
* This DC is private and does not need to be released.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* window);
#endif
#if defined(GLFW_EXPOSE_NATIVE_COCOA)
/*! @brief Returns the `CGDirectDisplayID` of the specified monitor.
*
* @return The `CGDirectDisplayID` of the specified monitor, or
* `kCGNullDirectDisplay` if an [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.1.
*
* @ingroup native
*/
GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor);
/*! @brief Returns the `NSWindow` of the specified window.
*
* @return The `NSWindow` of the specified window, or `nil` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
GLFWAPI id glfwGetCocoaWindow(GLFWwindow* window);
#endif
#if defined(GLFW_EXPOSE_NATIVE_NSGL)
/*! @brief Returns the `NSOpenGLContext` of the specified window.
*
* @return The `NSOpenGLContext` of the specified window, or `nil` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref
* GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
GLFWAPI id glfwGetNSGLContext(GLFWwindow* window);
#endif
#if defined(GLFW_EXPOSE_NATIVE_X11)
/*! @brief Returns the `Display` used by GLFW.
*
* @return The `Display` used by GLFW, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
GLFWAPI Display* glfwGetX11Display(void);
/*! @brief Returns the `RRCrtc` of the specified monitor.
*
* @return The `RRCrtc` of the specified monitor, or `None` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.1.
*
* @ingroup native
*/
GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor);
/*! @brief Returns the `RROutput` of the specified monitor.
*
* @return The `RROutput` of the specified monitor, or `None` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.1.
*
* @ingroup native
*/
GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* monitor);
/*! @brief Returns the `Window` of the specified window.
*
* @return The `Window` of the specified window, or `None` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
GLFWAPI Window glfwGetX11Window(GLFWwindow* window);
/*! @brief Sets the current primary selection to the specified string.
*
* @param[in] string A UTF-8 encoded string.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
*
* @pointer_lifetime The specified string is copied before this function
* returns.
*
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref clipboard
* @sa glfwGetX11SelectionString
* @sa glfwSetClipboardString
*
* @since Added in version 3.3.
*
* @ingroup native
*/
GLFWAPI void glfwSetX11SelectionString(const char* string);
/*! @brief Returns the contents of the current primary selection as a string.
*
* If the selection is empty or if its contents cannot be converted, `NULL`
* is returned and a @ref GLFW_FORMAT_UNAVAILABLE error is generated.
*
* @return The contents of the selection as a UTF-8 encoded string, or `NULL`
* if an [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
*
* @pointer_lifetime The returned string is allocated and freed by GLFW. You
* should not free it yourself. It is valid until the next call to @ref
* glfwGetX11SelectionString or @ref glfwSetX11SelectionString, or until the
* library is terminated.
*
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref clipboard
* @sa glfwSetX11SelectionString
* @sa glfwGetClipboardString
*
* @since Added in version 3.3.
*
* @ingroup native
*/
GLFWAPI const char* glfwGetX11SelectionString(void);
#endif
#if defined(GLFW_EXPOSE_NATIVE_GLX)
/*! @brief Returns the `GLXContext` of the specified window.
*
* @return The `GLXContext` of the specified window, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref
* GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window);
/*! @brief Returns the `GLXWindow` of the specified window.
*
* @return The `GLXWindow` of the specified window, or `None` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref
* GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.2.
*
* @ingroup native
*/
GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* window);
#endif
#if defined(GLFW_EXPOSE_NATIVE_WAYLAND)
/*! @brief Returns the `struct wl_display*` used by GLFW.
*
* @return The `struct wl_display*` used by GLFW, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.2.
*
* @ingroup native
*/
GLFWAPI struct wl_display* glfwGetWaylandDisplay(void);
/*! @brief Returns the `struct wl_output*` of the specified monitor.
*
* @return The `struct wl_output*` of the specified monitor, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.2.
*
* @ingroup native
*/
GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor);
/*! @brief Returns the main `struct wl_surface*` of the specified window.
*
* @return The main `struct wl_surface*` of the specified window, or `NULL` if
* an [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.2.
*
* @ingroup native
*/
GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window);
#endif
#if defined(GLFW_EXPOSE_NATIVE_EGL)
/*! @brief Returns the `EGLDisplay` used by GLFW.
*
* @return The `EGLDisplay` used by GLFW, or `EGL_NO_DISPLAY` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @remark Because EGL is initialized on demand, this function will return
* `EGL_NO_DISPLAY` until the first context has been created via EGL.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
GLFWAPI EGLDisplay glfwGetEGLDisplay(void);
/*! @brief Returns the `EGLContext` of the specified window.
*
* @return The `EGLContext` of the specified window, or `EGL_NO_CONTEXT` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref
* GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window);
/*! @brief Returns the `EGLSurface` of the specified window.
*
* @return The `EGLSurface` of the specified window, or `EGL_NO_SURFACE` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref
* GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* window);
#endif
#if defined(GLFW_EXPOSE_NATIVE_OSMESA)
/*! @brief Retrieves the color buffer associated with the specified window.
*
* @param[in] window The window whose color buffer to retrieve.
* @param[out] width Where to store the width of the color buffer, or `NULL`.
* @param[out] height Where to store the height of the color buffer, or `NULL`.
* @param[out] format Where to store the OSMesa pixel format of the color
* buffer, or `NULL`.
* @param[out] buffer Where to store the address of the color buffer, or
* `NULL`.
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref
* GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.3.
*
* @ingroup native
*/
GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* window, int* width, int* height, int* format, void** buffer);
/*! @brief Retrieves the depth buffer associated with the specified window.
*
* @param[in] window The window whose depth buffer to retrieve.
* @param[out] width Where to store the width of the depth buffer, or `NULL`.
* @param[out] height Where to store the height of the depth buffer, or `NULL`.
* @param[out] bytesPerValue Where to store the number of bytes per depth
* buffer element, or `NULL`.
* @param[out] buffer Where to store the address of the depth buffer, or
* `NULL`.
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref
* GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.3.
*
* @ingroup native
*/
GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* window, int* width, int* height, int* bytesPerValue, void** buffer);
/*! @brief Returns the `OSMesaContext` of the specified window.
*
* @return The `OSMesaContext` of the specified window, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref
* GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.3.
*
* @ingroup native
*/
GLFWAPI OSMesaContext glfwGetOSMesaContext(GLFWwindow* window);
#endif
#ifdef __cplusplus
}
#endif
#endif /* _glfw3_native_h_ */

File diff suppressed because it is too large Load Diff

55
include/Errors.hpp Normal file
View File

@ -0,0 +1,55 @@
#pragma once
#ifndef _NB_ERROR
#define _NB_ERROR
#include <exception>
#include <string.h>
#include <string>
#include <unordered_map>
namespace nb {
typedef std::unordered_map<unsigned int, const char*> ErrorCodeMap;
class Error : public std::exception {
public:
Error(const unsigned int code=0, std::exception* const trace=nullptr) noexcept;
Error(std::string, std::exception* const=nullptr) noexcept;
Error(const Error&) noexcept;
unsigned int code() const noexcept;
virtual const char* type() const noexcept final;
virtual const char* what() const noexcept override final;
template<typename NBError>
friend const char* ErrorCodeLookup(unsigned int);
protected:
static const ErrorCodeMap ErrorCodes;
Error(
const unsigned int,
std::string,
std::exception* const,
unsigned int line=0,
std::string filename=""
) noexcept;
const char* _type;
const unsigned int _code;
std::string _msg;
};
template<typename NBError>
const char* ErrorCodeLookup(unsigned int code) {
for (auto kv : NBError::ErrorCodes) {
if (kv.first == code) {
return kv.second;
}
}
throw Error(666);
}
} // namespace nb
#endif // _NB_ERROR

35
include/GLLoad.h Normal file
View File

@ -0,0 +1,35 @@
#pragma once
#ifndef _NB_OPENGL_LOADER
#define _NB_OPENGL_LOADER
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <string>
namespace NB {
static unsigned int __NB_GL_DEBUG_ERROR_CODE__;
static std::string formatDebugString(const std::string& msg, const std::string& file="", int line=-1) {
std::string ret = "";
if (file != "") {
ret += "In file " + file;
if (line >= 0) {
ret += " at line " + std::to_string(line);
}
ret += ":\n\t";
}
return ret + msg;
}
}
#define NB_GL_DEBUG_THROW(cmd, when) while(NB::__NB_GL_DEBUG_ERROR_CODE__=glGetError()){\
std::cout << "[GL ERROR]: " << NB::__NB_GL_DEBUG_ERROR_CODE__;\
std::cout << " " << when << " " << cmd << "\n";\
}
#define NB_GL_DEBUG(cmd) NB_GL_DEBUG_THROW(#cmd, "before"); cmd; NB_GL_DEBUG_THROW(#cmd, "after");
#endif

123
include/ThreadsafeQueue.hpp Normal file
View File

@ -0,0 +1,123 @@
#pragma once
#ifndef _NB_UTIL_THREADSAFE_QUEUE
#define _NB_UTIL_THREADSAFE_QUEUE
#include <condition_variable>
#include <memory>
#include <mutex>
#include <queue>
#include <type_traits>
namespace nb {
template<typename T, bool isPoly>
class ThreadsafeQueue_impl;
// Non-polymorphic
template<typename T>
class ThreadsafeQueue_impl<T, false> {
public:
bool empty() const {
std::lock_guard<std::mutex> lock(_mutex);
return _queue.empty();
}
unsigned int size() const {
std::lock_guard<std::mutex> lock(_mutex);
return _queue.size();
}
template<typename U>
void push(U&& val) {
std::lock_guard<std::mutex> lock(_mutex);
_queue.push(std::forward<U>(val));
_cond.notify_one();
}
bool pop(std::shared_ptr<T>& dest) {
std::lock_guard<std::mutex> lock(_mutex);
if (_queue.empty()) { return false; }
dest = std::make_shared<T>(std::move(_queue.front()));
_queue.pop();
return true;
}
std::shared_ptr<T> popBlock() {
std::unique_lock<std::mutex> lock(_mutex);
_cond.wait(lock, [&]{ return !_queue.empty(); });
auto ret = std::make_shared<T>(std::move(_queue.front()));
_queue.pop();
return ret;
}
protected:
ThreadsafeQueue_impl() {}
std::queue<T> _queue;
std::condition_variable _cond;
mutable std::mutex _mutex;
};
// Polymorphic
template<typename T>
class ThreadsafeQueue_impl<T, true> {
public:
bool empty() const {
std::lock_guard<std::mutex> lock(_mutex);
return _queue.empty();
}
unsigned int size() const {
std::lock_guard<std::mutex> lock(_mutex);
return _queue.size();
}
template<typename U>
void push(U&& val) {
std::lock_guard<std::mutex> lock(_mutex);
std::shared_ptr<T> newval = std::make_shared<T>(std::forward<U>(val));
_queue.push(newval);
_cond.notify_one();
}
bool pop(std::shared_ptr<T>& dest) {
std::lock_guard<std::mutex> lock(_mutex);
if (_queue.empty()) { return false; }
dest = std::move(_queue.front());
_queue.pop();
return true;
}
std::shared_ptr<T> popBlock() {
std::unique_lock<std::mutex> lock(_mutex);
_cond.wait(lock, [&]{ return !_queue.empty(); });
auto ret = std::move(_queue.front());
_queue.pop();
return ret;
}
protected:
ThreadsafeQueue_impl() {}
std::queue<std::shared_ptr<T>> _queue;
std::condition_variable _cond;
mutable std::mutex _mutex;
};
template<typename T>
class ThreadsafeQueue : public ThreadsafeQueue_impl<T, std::is_polymorphic<T>::value> {
public:
using Implementation = ThreadsafeQueue_impl<T, std::is_polymorphic<T>::value>;
ThreadsafeQueue() = default;
~ThreadsafeQueue() = default;
ThreadsafeQueue(ThreadsafeQueue& rhs) = delete;
ThreadsafeQueue& operator=(ThreadsafeQueue& rhs) = delete;
ThreadsafeQueue(ThreadsafeQueue&& rhs) = delete;
ThreadsafeQueue& operator=(ThreadsafeQueue&& rhs) = delete;
operator bool() const { return !Implementation::empty(); }
};
} // namespace nb
#endif // _NB_UTIL_THREADSAFE_QUEUE

View File

@ -2,37 +2,67 @@
#ifndef _NB_WINDOW
#define _NB_WINDOW
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include "GLLoad.h"
#include <atomic>
#include <array>
#include <string>
#include <iostream>
#include <map>
#include <stdexcept>
#include <string>
namespace NB {
class GLError : public std::runtime_error {
public:
GLError(const std::string&);
};
class WindowError : public std::runtime_error {
public:
WindowError(const std::string&);
};
class Window {
public:
static bool StrictInitialization;
static int getGLFWHint(int);
static int setGLFWHint(int, int);
static Window* getCurrent();
Window(const std::array<uint16_t, 2>, const char*, GLFWmonitor* initMonitor=NULL, GLFWwindow* initWindow=NULL);
Window(const uint16_t, const uint16_t, const char*, GLFWmonitor* initMonitor=NULL, GLFWwindow* initWindow=NULL);
~Window();
int init();
int getWindowHint(int) const;
GLFWwindow* getWindow() const;
std::array<uint16_t, 2> getSize() const;
float getAspectRatio() const;
std::string getName() const;
int init();
int setWindowHint(int, int);
void setCurrent();
void resize(const std::array<uint16_t, 2>);
void resize(const uint16_t x, const uint16_t y);
protected:
static std::atomic<uint8_t> windowCount;
static std::map<GLFWwindow*, Window*> WindowContexts;
static std::map<int, int> GLFWHints;
static Window* _current;
static bool _glfw_init;
static bool checkKillGLFW();
std::map<int, int> windowHints;
std::array<uint16_t, 2> windowSize;
float _aspect_ratio;
std::string windowName;
bool ready=false, running=false;
GLFWwindow* window;
GLFWmonitor* monitor;
GLFWwindow* shareWindow;
bool _init = false;
int gladResponse = -1;
};
};

View File

View File

@ -0,0 +1,58 @@
#include "Errors.hpp"
namespace nb {
// class Error
const ErrorCodeMap Error::ErrorCodes = {
{0, "Undefined error."},
{666, "Unrecognized error code."}
};
Error::Error(
const unsigned int code,
std::string msg,
std::exception* const trace,
unsigned int line,
std::string filename
) noexcept : _code{code} {
_msg = std::string(type());
_msg += ":" + std::to_string(code);
if (line && filename.size()) {
_msg += " in \'" + filename + "\':" + std::to_string(line);
}
_msg += "\n\t" + msg;
if (trace) {
_msg += "\nTraceback - " + std::string(trace->what());
}
}
Error::Error(const unsigned int code, std::exception* const trace) noexcept
: Error(code, ErrorCodeLookup<Error>(code), trace) {}
Error::Error(std::string msg, std::exception* const trace) noexcept
: Error(0, msg, trace) {}
Error::Error(const Error& cp) noexcept
: _type{cp._type}, _code{cp._code}, _msg{cp._msg} {}
unsigned int Error::code() const noexcept { return _code; }
const char* Error::type() const noexcept { return this->_type; }
const char* Error::what() const noexcept { return _msg.c_str(); }
/* constexpr const char* Error::lookup(unsigned int code) noexcept {
char* ret = new char[512];
switch(code) {
case 0:
strcpy(ret, "General ");
strcat(ret, this->type());
break;
default:
strcpy(ret, this->lookup(code));
break;
}
return ret;
} */
}

View File

View File

@ -0,0 +1,3 @@
add_library(NBWindow Window.cpp ./../../../glad/src/glad.c)
target_link_libraries(NBWindow glfw)

170
src/NBWindow/Window.cpp Normal file
View File

@ -0,0 +1,170 @@
#include "Window.h"
namespace NB {
std::map<GLFWwindow*, Window*> Window::WindowContexts = {};
std::map<int, int> Window::GLFWHints = {};
bool Window::StrictInitialization = true;
bool Window::_glfw_init = false;
Window* Window::_current = nullptr;
static std::map<int, int> defailt_window_hints = {
{GLFW_CONTEXT_VERSION_MAJOR, 3},
{GLFW_CONTEXT_VERSION_MINOR, 1},
{GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE}
#ifdef _NB_GL_DEBUG_ON
, {GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE}
#endif
};
GLError::GLError(const std::string& msg) : std::runtime_error(msg) {}
WindowError::WindowError(const std::string &msg) : std::runtime_error(msg) {}
int Window::getGLFWHint(int hint_key) {
if (GLFWHints.find(hint_key) == GLFWHints.end()) {
return 0;
} else {
return GLFWHints.at(hint_key);
}
}
int Window::setGLFWHint(int hint_key, int hint_val) {
if (Window::_glfw_init) {
throw GLError("Cannot set GLFW hint after window is initialized.");
} else {
GLFWHints[hint_key] = hint_val;
}
return GLFWHints[hint_key];
}
Window* Window::getCurrent() {
return _current;
}
bool Window::checkKillGLFW() {
if(Window::WindowContexts.size() == 0 && _glfw_init) {
glfwTerminate();
Window::_glfw_init = false;
return true;
}
return false;
}
Window::Window(const uint16_t x, const uint16_t y, const char* initName, GLFWmonitor* initMonitor, GLFWwindow* initWindow) {
if (!Window::_glfw_init) {
for (const auto& hint : Window::GLFWHints) {
glfwInitHint(hint.first, hint.second);
}
int glfwResponse = glfwInit();
if (glfwResponse) {
Window::_glfw_init = true;
} else {
if (Window::StrictInitialization) {
throw GLError("Failed to load GLFW with glfwInit()="+std::to_string(glfwResponse)+".");
}
}
}
windowSize = {x, y};
_aspect_ratio = float(x)/float(y);
windowName = std::string(initName);
monitor = initMonitor;
shareWindow = initWindow;
for (const auto& hint: defailt_window_hints) {
windowHints[hint.first] = hint.second;
}
}
Window::Window(const std::array<uint16_t, 2> initSize, const char* initName, GLFWmonitor* initMonitor, GLFWwindow* initWindow) :
Window(initSize[0], initSize[1], initName, initMonitor, initWindow){}
Window::~Window() {
glfwSetWindowShouldClose(window, true);
glfwDestroyWindow(window);
Window::WindowContexts.erase(window);
if (Window::WindowContexts.size()==0) {
glfwTerminate();
}
}
void Window::setCurrent() {
_current = this;
glfwMakeContextCurrent(window);
}
int Window::getWindowHint(int hint_key) const {
if (windowHints.find(hint_key) == windowHints.end()) {
return 0;
} else {
return windowHints.at(hint_key);
}
}
int Window::setWindowHint(int hint_key, int hint_val) {
if (_init) {
throw WindowError("Cannot set window hint after window is initialized.");
} else {
windowHints[hint_key] = hint_val;
}
return windowHints[hint_key];
}
int Window::init() {
if (!_glfw_init) {
throw GLError("GLFW has not been initialized.");
}
for (const auto& hint : windowHints) {
glfwWindowHint(hint.first, hint.second);
}
window = glfwCreateWindow(windowSize[0], windowSize[1], windowName.c_str(), monitor, shareWindow);
if (window == NULL) {
Window::WindowContexts.erase(window);
if (Window::WindowContexts.size()==0 && Window::_glfw_init) { glfwTerminate(); }
if (Window::StrictInitialization) {
throw WindowError("Could not create window in glfwCreateWindow().");
}
}
glfwMakeContextCurrent(window);
Window::WindowContexts[window] = this;
gladResponse = gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);
if (!gladResponse) {
Window::checkKillGLFW();
if (Window::StrictInitialization) {
throw GLError("Failed to load GLAD with \
gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)="+\
std::to_string(gladResponse)+"."
);
}
}
_init = true;
glViewport(0, 0, windowSize[0], windowSize[1]);
return gladResponse;
}
GLFWwindow* Window::getWindow() const {
return window;
}
float Window::getAspectRatio() const { return _aspect_ratio; }
std::array<uint16_t, 2> Window::getSize() const {
return windowSize;
}
std::string Window::getName() const {
return windowName;
}
void Window::resize(const std::array<uint16_t, 2> newSize) {
windowSize = newSize;
_aspect_ratio = float(newSize[0]) / float(newSize[1]);
glViewport(0, 0, windowSize[0], windowSize[1]);
glfwSetWindowSize(window, windowSize[0], windowSize[1]);
}
void Window::resize(const uint16_t x, const uint16_t y) { resize({x, y}); }
};

View File

@ -1,91 +0,0 @@
#include "Window.h"
namespace NB {
std::atomic<uint8_t> Window::windowCount(0);
Window::Window(const uint16_t x, const uint16_t y, const char* initName, GLFWmonitor* initMonitor, GLFWwindow* initWindow) {
if (windowCount == 0) {
glfwInit();
}
windowSize = {x, y};
windowName = std::string(initName);
monitor = initMonitor;
shareWindow = initWindow;
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 4);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
window = glfwCreateWindow(windowSize[0], windowSize[0], windowName.c_str(), monitor, shareWindow);
if (window == NULL) {
std::cout << "NB::NBWINDOW::COULD NOT CREATE WINDOW(" << windowName << ")\n";
if (windowCount == 0) { glfwTerminate(); }
ready = false;
} else {
windowCount++;
ready = true;
}
}
Window::Window(const std::array<uint16_t, 2> initSize, const char* initName, GLFWmonitor* initMonitor, GLFWwindow* initWindow) :
Window(initSize[0], initSize[1], initName, initMonitor, initWindow){}
Window::~Window() {
glfwSetWindowShouldClose(window, true);
glfwDestroyWindow(window);
windowCount--;
if (windowCount == 0) {
glfwTerminate();
}
}
int Window::init() {
if (!ready) {
std::cout << "NB::NBWINDOW::NOT READY\n";
return -1;
}
glfwMakeContextCurrent(window);
if (!gladLoadGLLoader((GLADloadproc) glfwGetProcAddress)) {
std::cout << "NB::NBWINDOW::COULD NOT INITIALIZE GLAD\n";
if (windowCount == 0) { glfwTerminate(); }
return -1;
}
glViewport(0, 0, windowSize[0], windowSize[1]);
running=true;
return 0;
}
GLFWwindow* Window::getWindow() const {
return window;
}
std::array<uint16_t, 2> Window::getSize() const {
return windowSize;
}
std::string Window::getName() const {
return windowName;
}
void Window::resize(const std::array<uint16_t, 2> newSize) {
windowSize = newSize;
if (running) {
glViewport(0, 0, windowSize[0], windowSize[1]);
glfwSetWindowSize(window, windowSize[0], windowSize[1]);
}
}
void Window::resize(const uint16_t x, const uint16_t y) {
windowSize = {x, y};
if (running) {
glViewport(0, 0, windowSize[0], windowSize[1]);
glfwSetWindowSize(window, windowSize[0], windowSize[1]);
}
}
};

16
tests/CMakeLists.txt Normal file
View File

@ -0,0 +1,16 @@
cmake_minimum_required(VERSION 3.26.0)
project(gtest_Graphics VERSION 0.1.0 LANGUAGES C CXX)
include(FetchContent)
FetchContent_Declare(
gtest
URL https://github.com/google/googletest/archive/refs/tags/release-1.12.1.zip
)
if (WIN32)
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(gtest)
endif()
include(GoogleTest)
set(GTEST_COLOR ON)
add_subdirectory(./ErrorTest)

View File

@ -0,0 +1,5 @@
cmake_minimum_required(VERSION 3.26.0)
project(gtest_Graphics VERSION 0.1.0 LANGUAGES C CXX)
add_executable(ErrorTest main.cpp)
target_link_libraries(ErrorTest NBCore)

31
tests/ErrorTest/main.cpp Normal file
View File

@ -0,0 +1,31 @@
#include "Errors.hpp"
#include <iostream>
using namespace nb;
class TestError : public nb::Error {
public:
TestError(unsigned int code, nb::Error* const trace=nullptr) : _type("nb::TestError"), Error(code, ErrorCodeLookup<TestError>(code), trace) {}
friend const char* ErrorCodeLookup<TestError>(unsigned int);
protected:
static const nb::ErrorCodeMap ErrorCodes;
const char* _type;
};
const ErrorCodeMap TestError::ErrorCodes{
{0, "Hey!"},
{1, "How"},
{2, "You"},
{3, "Doin"}
};
int main() {
TestError a(0);
TestError b(1, &a);
TestError c(2, &b);
throw TestError(3, &c);
return 0;
}