diff --git a/TODO.md b/TODO.md index ef9a5b7..27e3ccd 100644 --- a/TODO.md +++ b/TODO.md @@ -16,11 +16,11 @@ ## Hibis UI (NEED A NAME) - [ ] GUI creation - [ ] Text Object (rendering via SDL2_TTF (RSDL) or FreeType2 (EVERYTHING ELSE)) -## RSDL (2D ONLY) +## RGLCore (2D AND 3D) - [X] Window creation -- [X] Renderer creation -- [X] Render present -- [X] Clear renderer +- [ ] Renderer creation +- [ ] Render present +- [ ] Clear renderer - [ ] Texture drawing - [ ] Draw section of texture from sprite sheet ## RVK (2D AND 3D, NEEDS A NAME) diff --git a/core/engine/engine.cpp b/core/engine/engine.cpp index 97e42d1..9fc702c 100644 --- a/core/engine/engine.cpp +++ b/core/engine/engine.cpp @@ -12,7 +12,13 @@ namespace hibis { //watch.start(); - this->mLoggerCallback(Information, "Started Hibis [using v" + (std::string)getEngineVersion() + "]!"); + mLoggerCallback(Information, "Starting FreeType2 library..."); + int err = FT_Init_FreeType(&mFreeTypeLibrary); + if (err) { + mLoggerCallback(Fatal, "Failed to init FreeType2"); + } + + mLoggerCallback(Information, "Started Hibis [using v" + (std::string)getEngineVersion() + "]!"); } Engine::~Engine() { diff --git a/core/engine/engine.hpp b/core/engine/engine.hpp index 7926712..3b1d7e0 100644 --- a/core/engine/engine.hpp +++ b/core/engine/engine.hpp @@ -2,6 +2,7 @@ #include #include +#include #include "../renderer/renderer.hpp" #include "../callback.hpp" @@ -20,6 +21,8 @@ namespace hibis { void drawNodes(); const char* getEngineVersion(); + + FT_Library mFreeTypeLibrary; private: Renderer* mRenderer; //StopWatch watch; diff --git a/core/renderer/renderer.hpp b/core/renderer/renderer.hpp index 5f955ed..f993bb6 100644 --- a/core/renderer/renderer.hpp +++ b/core/renderer/renderer.hpp @@ -1,13 +1,17 @@ #pragma once +#include + #include "../math/types.hpp" #include "../resources/resource.hpp" #include "../resources/texture.hpp" -#include +#include "../callback.hpp" namespace hibis { class Renderer { public: + Renderer(LoggerCallback logger) : mLogger(logger) {} + // Draw virtual void clearScreen(Color col) = 0; virtual void renderCurrent() = 0; @@ -26,5 +30,7 @@ namespace hibis { virtual void setWindowTitle(std::string title) = 0; bool mKeepOpen = true; + protected: + LoggerCallback mLogger; }; } diff --git a/core/resources/font.cpp b/core/resources/font.cpp new file mode 100644 index 0000000..0b317ac --- /dev/null +++ b/core/resources/font.cpp @@ -0,0 +1,22 @@ +#include "font.hpp" +#include "../pragmautil.hpp" + +namespace hibis { + Font::Font(FT_Library& lib, const char* path, u_int16_t size) { + int err = FT_New_Face(lib, path, 0, &mFontFace); + if (err) { + TODO("Error message involving `int err`"); + } + + setFontSize(size); + mPath = path; + } + + Font::~Font() {} + + void Font::setFontSize(u_int16_t newSize) { + FT_Set_Pixel_Sizes(mFontFace, 0, newSize); + mCurrentSize = newSize; + } + +} diff --git a/core/resources/font.hpp b/core/resources/font.hpp new file mode 100644 index 0000000..e98146c --- /dev/null +++ b/core/resources/font.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include + +#include "resource.hpp" + +namespace hibis { + class Font : public Resource { + public: + Font(FT_Library& lib, const char* path, u_int16_t size); + ~Font(); + + void setFontSize(u_int16_t newSize); + u_int16_t getCurrentSize() { return mCurrentSize; } + + const char* mPath; + private: + FT_Face mFontFace; + + u_int16_t mCurrentSize; + }; +} diff --git a/meson.build b/meson.build index 42233ea..da627f5 100644 --- a/meson.build +++ b/meson.build @@ -12,19 +12,21 @@ include_dirs = include_directories('./external') # Files libhibis_src_core = files('core/engine/engine.cpp') -libhibis_src_resources = files('core/resources/texture.cpp') +libhibis_src_resources = files('core/resources/texture.cpp', 'core/resources/font.cpp') libhibis_src = [libhibis_src_core, libhibis_src_resources] -libhibis_rsdl_src = files('renderer/rsdl/rsdl.cpp', 'renderer/rsdl/resources/font.cpp') +libhibis_rglcore_src = files('renderer/rglcore/rglcore.cpp') libhibis_test_src = files('test/app.cpp') # Dependencies -libsdl2 = dependency('SDL2') -libsdl2_ttf = dependency('SDL2_ttf') +libgl = dependency('gl') +libglfw = dependency('glfw3') +libglew = dependency('GLEW') libfmt = dependency('fmt') +libfreetype2 = dependency('freetype2') liblodepng = static_library('lodepng', 'external/lodepng/lodepng.cpp') # Compile -libhibis = library('hibis', libhibis_src, include_directories: include_dirs, link_with: liblodepng) -libhibis_rsdl = library('hibis_rsdl', libhibis_rsdl_src, include_directories: [include_dirs, './core'], link_with: libhibis, dependencies: [libsdl2, libsdl2_ttf, libfmt]) -hibistest = executable('hibistest.exec', libhibis_test_src, include_directories: [include_dirs, './core', './renderer/rsdl'], link_with: [libhibis, libhibis_rsdl], dependencies: [libsdl2, libsdl2_ttf, libfmt]) +libhibis = library('hibis', libhibis_src, include_directories: include_dirs, link_with: liblodepng, dependencies: [libfreetype2]) +libhibis_rglcore = library('hibis_rglcore', libhibis_rglcore_src, include_directories: [include_dirs, './core'], link_with: libhibis, dependencies: [libfreetype2, libgl, libglfw, libglew, libfmt]) +hibistest = executable('hibistest.exec', libhibis_test_src, include_directories: [include_dirs, './core', './renderer/rglcore'], link_with: [libhibis, libhibis_rglcore], dependencies: [libfreetype2, libgl, libglfw, libglew, libfmt]) diff --git a/renderer/rglcore/rglcore.cpp b/renderer/rglcore/rglcore.cpp new file mode 100644 index 0000000..d4c40fe --- /dev/null +++ b/renderer/rglcore/rglcore.cpp @@ -0,0 +1,71 @@ +#include + +#include "rglcore.hpp" + +namespace hibis::rglcore { + RGLCore::RGLCore(std::string title, IntVec2 size, LoggerCallback callback) : Renderer(callback) { + mLogger(Information, "Preparing GLFW3..."); + if (!glfwInit()) { + mLogger(Fatal, "GLFW couldn't be initialised!"); + exit(1); + } + + mLogger(Information, "Creating GLFWwindow..."); + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + mWindow = glfwCreateWindow(size.x, size.y, title.c_str(), NULL, NULL); + if (!mWindow) { + mLogger(Fatal, "Window could not be created!"); + exit(1); + } + + glfwMakeContextCurrent(mWindow); + + mLogger(Information, "Preparing GLEW..."); + glewExperimental = GL_FALSE; + GLenum err = glewInit(); + + if (err != GLEW_OK) { + mLogger(Fatal, "GLEW could not be created due to GLEW err " + std::to_string(err)); + exit(err); + } + + mLogger(Information, "Setting viewport..."); + glViewport(0, 0, size.x, size.y); + + mLogger(Information, "Finished setting up RGLCore!"); + } + + RGLCore::~RGLCore() { + glfwDestroyWindow(mWindow); + glfwTerminate(); + } + + // Draw + void RGLCore::clearScreen(Color col) { + float r = (float)(col.r) / 255, g = (float)(col.g) / 255, b = (float)(col.b) / 255, a = (float)(col.a) / 255; + glClearColor(r, g, b, a); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } + + void RGLCore::renderCurrent() { + glfwSwapBuffers(mWindow); + } + + void RGLCore::drawText(Resource* resource, std::string text, IntVec2 pos, Color color) {} + void RGLCore::drawTexture(Texture* resource, float scale, IntVec2 pos) {} + + // Pre and Post draw + void RGLCore::preDraw() {} + void RGLCore::postDraw() {} + + void RGLCore::update() { + mKeepOpen = !glfwWindowShouldClose(mWindow); + glfwPollEvents(); + } + + void RGLCore::setWindowTitle(std::string title) { + glfwSetWindowTitle(mWindow, title.c_str()); + } +} diff --git a/renderer/rglcore/rglcore.hpp b/renderer/rglcore/rglcore.hpp new file mode 100644 index 0000000..487b5c2 --- /dev/null +++ b/renderer/rglcore/rglcore.hpp @@ -0,0 +1,37 @@ +#pragma once + +#include +#include + +#include +#include FT_FREETYPE_H + +#include +#include + +namespace hibis::rglcore { + class RGLCore : public Renderer { + public: + RGLCore(std::string title, IntVec2 size, LoggerCallback callback); + ~RGLCore(); + + // Draw + void clearScreen(Color col) override; + void renderCurrent() override; + + void drawText(Resource* resource, std::string text, IntVec2 pos, Color color) override; + void drawTexture(Texture* resource, float scale, IntVec2 pos) override; + + // Pre and Post draw + void preDraw() override; + void postDraw() override; + + // Update + void update() override; + + // Util + void setWindowTitle(std::string title) override; + private: + GLFWwindow* mWindow; + }; +} diff --git a/renderer/rsdl/resources/font.cpp b/renderer/rsdl/resources/font.cpp deleted file mode 100644 index 5d0e86e..0000000 --- a/renderer/rsdl/resources/font.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include -#include -#include -#include "font.hpp" - -namespace hibis::rsdl { - Font::Font(std::string path, uint size) { - this->mSize = size; - this->mPath = path; - loadFont(); - } - - Font::~Font() { - TTF_CloseFont(mLoadedFont); - } - - void Font::loadFont(bool reload) { - // If already loaded, close font - if (mLoadedFont != NULL) { - TTF_CloseFont(mLoadedFont); - mLoadedFont = NULL; - } - - mLoadedFont = TTF_OpenFont(mPath.c_str(), mSize); - - // Do the message - if (!mDidReload) { - std::cout << fmt::format((reload ? "Reloaded font from" : "Loaded font at") + (std::string)" {}", mPath) << std::endl; - mDidReload = reload; - } - } -} diff --git a/renderer/rsdl/resources/font.hpp b/renderer/rsdl/resources/font.hpp deleted file mode 100644 index 2c64f1c..0000000 --- a/renderer/rsdl/resources/font.hpp +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include -#include - -#include - -namespace hibis::rsdl { - class Font : public Resource { - public: - Font(std::string path, uint size); - - ~Font(); - - uint getFontSize() { return mSize; } - - void setFontSize(uint newSize) { mSize = newSize; loadFont(true); } - - TTF_Font* mLoadedFont = NULL; - private: - void loadFont(bool reload = false); - uint mSize; - std::string mPath; - - bool mDidReload = false; - }; -} diff --git a/renderer/rsdl/rsdl.cpp b/renderer/rsdl/rsdl.cpp deleted file mode 100644 index a3feb78..0000000 --- a/renderer/rsdl/rsdl.cpp +++ /dev/null @@ -1,101 +0,0 @@ -#include - -#include -#include "rsdl.hpp" -#include "resources/font.hpp" - -#include - -namespace hibis::rsdl { - RSDL::RSDL(std::string title, IntVec2 size, LoggerCallback callback) { - mLoggerCallback = callback; - - SDL_Init(SDL_INIT_VIDEO); - - // Create window. `title` is cast to a char* here as tostd::stringz returns an immutable char* (causing an error) - mWindow = SDL_CreateWindow(title.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, - size.x, size.y, SDL_WINDOW_RESIZABLE); - - if (mWindow == NULL) { - mLoggerCallback(Fatal, fmt::format("Couldn't create window! what: {}", SDL_GetError())); - SDL_Quit(); - exit(1); - } - - mRendererContext = SDL_CreateRenderer(mWindow, -1, SDL_RENDERER_ACCELERATED); - - if (mRendererContext == NULL) { - mLoggerCallback(Fatal, fmt::format("Couldn't create renderer! what: {}", SDL_GetError())); - SDL_DestroyWindow(mWindow); - SDL_Quit(); - exit(1); - } - - if (TTF_Init() != 0) { - mLoggerCallback(Fatal, fmt::format("Couldn't load SDL_TTF! what: %d", TTF_GetError())); - SDL_DestroyRenderer(mRendererContext); - SDL_DestroyWindow(mWindow); - SDL_Quit(); - TTF_Quit(); - exit(1); - } - } - - RSDL::~RSDL() { - TTF_Quit(); - SDL_DestroyRenderer(mRendererContext); - SDL_DestroyWindow(mWindow); - SDL_Quit(); - } - - void RSDL::clearScreen(Color col) { - SDL_SetRenderDrawColor(mRendererContext, col.r, col.g, col.b, col.a); - SDL_RenderClear(mRendererContext); - } - - void RSDL::renderCurrent() { - SDL_UpdateWindowSurface(mWindow); - SDL_RenderPresent(mRendererContext); - } - - void RSDL::drawText(Resource* resource, std::string text, IntVec2 pos, Color color) { - WARNING("(Tulip, this is abysmal) Avoid remaking textures every time text has to be drawn") - if (Font* font = (Font*)resource) { - SDL_Surface* textSurface = TTF_RenderText_Solid(font->mLoadedFont, text.c_str(), SDL_Color {color.r, color.g, color.b, color.a }); - SDL_Texture* textTexture = SDL_CreateTextureFromSurface(mRendererContext, textSurface); - - SDL_Rect textRect; - textRect.x = pos.x; - textRect.y = pos.y; - - TTF_SizeText(font->mLoadedFont, text.c_str(), &textRect.w, &textRect.h); - - SDL_RenderCopy(mRendererContext, textTexture, NULL, &textRect); - - SDL_DestroyTexture(textTexture); - SDL_FreeSurface(textSurface); - } - } - - void RSDL::drawTexture(Texture* resource, float scale, hibis::IntVec2 pos) { - if (resource->mData.empty()) return; - - TODO("this nonsense") - return; - } - - void RSDL::preDraw() {} - void RSDL::postDraw() {} - - void RSDL::update() { - SDL_Event event; - - while(SDL_PollEvent(&event)) { - if (event.type == SDL_QUIT) mKeepOpen = false; - } - } - - void RSDL::setWindowTitle(std::string title) { - SDL_SetWindowTitle(mWindow, title.c_str()); - } -} diff --git a/renderer/rsdl/rsdl.hpp b/renderer/rsdl/rsdl.hpp deleted file mode 100644 index 28f0ca6..0000000 --- a/renderer/rsdl/rsdl.hpp +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#include -#include -#include - -namespace hibis::rsdl { - /** \class RSDL - * Renderer implementation using SDL2 Renderer for the Hibis game engine - */ - class RSDL : public Renderer { - public: - RSDL(std::string title, IntVec2 size, LoggerCallback callback); - - ~RSDL(); - - void clearScreen(Color col = Color {0, 0, 0, 255}) override; - - void renderCurrent() override; - - void drawText(Resource* resource, std::string text, IntVec2 pos, Color color) override; - void drawTexture(Texture* resource, float scale, hibis::IntVec2 pos) override; - - void preDraw() override; - void postDraw() override; - - void update() override; - - void setWindowTitle(std::string title) override; - - private: - SDL_Window* mWindow; - SDL_Renderer* mRendererContext; - - LoggerCallback mLoggerCallback; - }; -} diff --git a/test/app.cpp b/test/app.cpp index 4b02c39..566e55f 100644 --- a/test/app.cpp +++ b/test/app.cpp @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include #include #include @@ -18,7 +18,7 @@ WARNING("Please avoid using MSVC in C++ projects utilising std::chrono and std:: #endif using namespace hibis; -using namespace hibis::rsdl; +using namespace hibis::rglcore; void logger(LoggingSeverity severity, std::string message) { std::string sevString; @@ -44,18 +44,18 @@ void logger(LoggingSeverity severity, std::string message) { } int main() { - RSDL renderer = RSDL("test", IntVec2 {800, 600}, &logger); + RGLCore renderer = RGLCore("test", IntVec2 {800, 600}, &logger); Engine engine = Engine(&renderer, &logger); #ifdef _WIN32 Font font = Font("C:\\Windows\\Fonts\\Arial.ttf", 16); #else - Font font = Font("/usr/share/fonts/noto/NotoSans-Light.ttf", 16); + Font font = Font(engine.mFreeTypeLibrary, "/usr/share/fonts/noto/NotoSans-Light.ttf", 16); #endif Texture image = Texture((char*)"test.png"); - unsigned char red = 0; + uint8_t red = 0; bool increaseRed = true; bool increaseSize = true; uint size = 16;