Rename Image to Texture, add PRAGMA macros to pragmautil.hpp, add some TODO() and WARNING() calls

This commit is contained in:
Tulpen 2023-05-27 18:11:46 +01:00
parent 5aaf616f34
commit 72d5aa0502
14 changed files with 207 additions and 160 deletions

1
.gitignore vendored
View file

@ -20,6 +20,7 @@ build
*.lst *.lst
*.user *.user
*.kdev4 *.kdev4
*.kate-swp
docs.json docs.json
__dummy.html __dummy.html
dub.selections.json dub.selections.json

26
README.md Normal file
View file

@ -0,0 +1,26 @@
# Hibis Game Engine
Hibis (short for Hibiscus ([named after the genus of flowering plants](https://en.wikipedia.org/wiki/Hibiscus))) is a work in progress game engine written in C++.<br>
The goal of this game engine is to provide each part of the engine (renderer, audio, physics etc.) in seperate libraries so you can easily make your own system if need be.
# Install
## Pre-compiled libraries
lmao they don't exist yet chill
## Compiling
### Note: MSVC
`MSVC` (Microsoft Visual C++ Compiler) is unsupported and I cannot guarentee that Hibis will compile using it. Please use another compiler like G++ or Ninja instead.
### Dependencies
To compile Hibis, you will need:
- Meson
- Meson-compatible compiler (recommended: Ninja or ccache + G++)
- A few minutes of your time
Each non-core library also has specific dependencies, including:
- (RSDL) SDL2
- (RSDL) SDL2_ttf
Linux users should be able to get all of these (except time) from their package manager.<br>
Windows users will need to use vcpkg or similar to easily get these dependencies.
### Actually Compiling
#### No Customising
Run `compile.sh` in the folder you cloned Hibis into.
#### Customising
In the folder you cloned Hibis into, run `meson build` to create a folder where the magic happens.<br>
Move into the build directory using CD and you can now use `meson configure` to adjust compile options.<br>
Once you have configured everything, run `meson compile` in the build directory and it should finish successfully.

View file

@ -36,3 +36,5 @@
- [ ] Physics Shape creation - [ ] Physics Shape creation
- [ ] Collision via raycasting - [ ] Collision via raycasting
- [ ] Option to *allow* for Physics Shapes to be able to be drawn (on by default, both compile time and run time, turn off at compile time via version(`-version=NoPhysShapeDraw`?)) - [ ] Option to *allow* for Physics Shapes to be able to be drawn (on by default, both compile time and run time, turn off at compile time via version(`-version=NoPhysShapeDraw`?))
## Examples
- [ ] Example Game: Megaman clone

View file

@ -1,16 +1,18 @@
#include "enginever.hpp" #include "enginever.hpp"
#include "engine.hpp" #include "engine.hpp"
#include <pragmautil.hpp>
#include <core/graphics/drawable.hpp>
namespace hibis { namespace hibis {
Engine::Engine(Renderer* renderer, LoggerCallback logger) { Engine::Engine(Renderer* renderer, LoggerCallback logger) {
this->renderer = renderer; this->renderer = renderer;
loggerCallback = logger; loggerCallback = logger;
previousProcessTick = 0.00001f; previousProcessTick = std::chrono::steady_clock::now();
previousPhysicsProcessTick = 0.00001f; previousPhysicsProcessTick = std::chrono::steady_clock::now();
//watch.start(); //watch.start();
this->loggerCallback(Information, "Started Hibis!"); this->loggerCallback(Information, "Started Hibis [using v" + (std::string)getEngineVersion() + "]!");
} }
Engine::~Engine() { Engine::~Engine() {
@ -18,32 +20,35 @@ namespace hibis {
} }
void Engine::runNodeProcesses() { void Engine::runNodeProcesses() {
// TODO: fix delta then adapt for runNodePhysicsProcesses TODO("check if delta calc is correct")
//const float current = watch.peek.total!"msecs" / 1_000; const std::chrono::time_point<std::chrono::steady_clock> current = std::chrono::steady_clock::now();
//float delta = (current - previousProcessTick); auto delta = std::chrono::duration<float>(current - previousProcessTick);
for (Node* node : nodeList) { for (Node* node : nodeList) {
node->physicsProcess(0.00f); node->process(delta.count());
} }
//this.previousProcessTick = watch.peek.total!"msecs" / 1_000; previousProcessTick = std::chrono::steady_clock::now();
} }
void Engine::runNodePhysicsProcesses() { void Engine::runNodePhysicsProcesses() {
// TODO: See above TODO const std::chrono::time_point<std::chrono::steady_clock> current = std::chrono::steady_clock::now();
// Schade! Have the wrong function content while I figure out how std.datetime.watch works auto delta = std::chrono::duration<float>(current - previousProcessTick);
//const float current = watch.peek.total!"msecs" / 1_000;
//float delta = (current - previousProcessTick);
for (Node* node : nodeList) { for (Node* node : nodeList) {
node->physicsProcess(0.00f); node->physicsProcess(delta.count());
} }
//this.previousPhysicsProcessTick = watch.peek.total!"msecs" / 1_000; previousProcessTick = std::chrono::steady_clock::now();
} }
void Engine::drawNodes() { void Engine::drawNodes() {
// TODO TODO("check if this works")
for (Node* node : nodeList) {
if (Drawable* drawNode = (Drawable*)&node) {
drawNode->draw(renderer);
}
}
} }
const char* Engine::getEngineVersion() { return HIBIS_VERSION; } const char* Engine::getEngineVersion() { return HIBIS_VERSION; }

View file

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <vector> #include <vector>
#include <chrono>
#include "../renderer/renderer.hpp" #include "../renderer/renderer.hpp"
#include "../callback.hpp" #include "../callback.hpp"
@ -22,8 +23,8 @@ namespace hibis {
private: private:
Renderer* renderer; Renderer* renderer;
//StopWatch watch; //StopWatch watch;
float previousProcessTick; std::chrono::time_point<std::chrono::steady_clock> previousProcessTick;
float previousPhysicsProcessTick; std::chrono::time_point<std::chrono::steady_clock> previousPhysicsProcessTick;
std::vector<Node*> nodeList; std::vector<Node*> nodeList;
LoggerCallback loggerCallback; LoggerCallback loggerCallback;

View file

@ -4,6 +4,7 @@
namespace hibis { namespace hibis {
class Drawable { class Drawable {
public:
virtual void draw(Renderer* renderer) = 0; virtual void draw(Renderer* renderer) = 0;
}; };
} }

View file

@ -1,7 +0,0 @@
#pragma once
#include "resource.hpp"
namespace hibis {
class Image : Resource {};
}

View file

@ -0,0 +1,11 @@
#pragma once
#include "resource.hpp"
#include <pragmautil.hpp>
namespace hibis {
TODO("Make this function")
class Texture : Resource {
void* data;
};
}

View file

@ -1,3 +1,9 @@
#pragma once #pragma once
// TODO: pragma // TODO: pragma
#define PRAGMA(x) _Pragma(#x)
#define MESSAGE(x) PRAGMA(message(x))
#define TODO(x) PRAGMA(message("TODO: " x))
#define WARNING(x) PRAGMA(GCC warning(x))
#define ERROR(x) PRAGMA(GCC error(x))

View file

@ -3,32 +3,30 @@
#include <fmt/format.h> #include <fmt/format.h>
#include "font.hpp" #include "font.hpp"
namespace hibis { namespace hibis::rsdl {
namespace rsdl { Font::Font(std::string path, uint size) {
Font::Font(std::string path, uint size) { this->size = size;
this->size = size; this->path = path;
this->path = path; loadFont();
loadFont(); }
}
Font::~Font() { Font::~Font() {
TTF_CloseFont(loadedFont);
}
void Font::loadFont(bool reload) {
// If already loaded, close font
if (loadedFont != NULL) {
TTF_CloseFont(loadedFont); TTF_CloseFont(loadedFont);
loadedFont = NULL;
} }
void Font::loadFont(bool reload) { loadedFont = TTF_OpenFont(path.c_str(), size);
// If already loaded, close font
if (loadedFont != NULL) {
TTF_CloseFont(loadedFont);
loadedFont = NULL;
}
loadedFont = TTF_OpenFont(path.c_str(), size); // Do the message
if (!didReload) {
// Do the message std::cout << fmt::format((reload ? "Reloaded font from" : "Loaded font at") + (std::string)" {}", path) << std::endl;
if (!didReload) { didReload = reload;
std::cout << fmt::format((reload ? "Reloaded font from" : "Loaded font at") + (std::string)" {}", path) << std::endl;
didReload = reload;
}
} }
} }
} }

View file

@ -5,26 +5,24 @@
#include <SDL2/SDL_ttf.h> #include <SDL2/SDL_ttf.h>
namespace hibis { namespace hibis::rsdl {
namespace rsdl { class Font : public Resource {
class Font : public Resource { public:
public: Font(std::string path, uint size);
Font(std::string path, uint size);
~Font(); ~Font();
uint getFontSize() { return size; } uint getFontSize() { return size; }
void setFontSize(uint newSize) { size = newSize; loadFont(true); } void setFontSize(uint newSize) { size = newSize; loadFont(true); }
TTF_Font* loadedFont = NULL; TTF_Font* loadedFont = NULL;
private: private:
void loadFont(bool reload = false); void loadFont(bool reload = false);
uint size; uint size;
std::string path; std::string path;
bool didReload = false; bool didReload = false;
}; };
}
} }

View file

@ -6,93 +6,94 @@
#include <pragmautil.hpp> #include <pragmautil.hpp>
namespace hibis { namespace hibis::rsdl {
namespace rsdl { RSDL::RSDL(std::string title, IntVec2 size, LoggerCallback callback) {
RSDL::RSDL(std::string title, IntVec2 size, LoggerCallback callback) { logger = callback;
logger = callback;
SDL_Init(SDL_INIT_VIDEO); SDL_Init(SDL_INIT_VIDEO);
// Create window. `title` is cast to a char* here as tostd::stringz returns an immutable char* (causing an error) // Create window. `title` is cast to a char* here as tostd::stringz returns an immutable char* (causing an error)
window = SDL_CreateWindow(title.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, window = SDL_CreateWindow(title.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
size.x, size.y, SDL_WINDOW_RESIZABLE); size.x, size.y, SDL_WINDOW_RESIZABLE);
if (window == NULL) { if (window == NULL) {
logger(Fatal, fmt::format("Couldn't create window! what: {}", SDL_GetError())); logger(Fatal, fmt::format("Couldn't create window! what: {}", SDL_GetError()));
SDL_Quit(); SDL_Quit();
exit(1); exit(1);
}
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (renderer == NULL) {
logger(Fatal, fmt::format("Couldn't create renderer! what: {}", SDL_GetError()));
SDL_DestroyWindow(window);
SDL_Quit();
exit(1);
}
if (TTF_Init() != 0) {
logger(Fatal, fmt::format("Couldn't load SDL_TTF! what: %d", TTF_GetError()));
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
TTF_Quit();
exit(1);
}
} }
RSDL::~RSDL() { renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
TTF_Quit();
if (renderer == NULL) {
logger(Fatal, fmt::format("Couldn't create renderer! what: {}", SDL_GetError()));
SDL_DestroyWindow(window);
SDL_Quit();
exit(1);
}
if (TTF_Init() != 0) {
logger(Fatal, fmt::format("Couldn't load SDL_TTF! what: %d", TTF_GetError()));
SDL_DestroyRenderer(renderer); SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window); SDL_DestroyWindow(window);
SDL_Quit(); SDL_Quit();
TTF_Quit();
exit(1);
} }
}
void RSDL::clearScreen(Color col) { RSDL::~RSDL() {
SDL_SetRenderDrawColor(renderer, col.r, col.g, col.b, col.a); TTF_Quit();
SDL_RenderClear(renderer); SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
}
void RSDL::clearScreen(Color col) {
SDL_SetRenderDrawColor(renderer, col.r, col.g, col.b, col.a);
SDL_RenderClear(renderer);
}
void RSDL::renderCurrent() {
SDL_UpdateWindowSurface(window);
SDL_RenderPresent(renderer);
}
void RSDL::drawText(Resource* resource, std::string text, IntVec2 pos, Color color) {
WARNING("tulip what the hell is this, this sucks.\nAvoid remaking textures every time text has to be drawn")
if (Font* font = (Font*)resource) {
SDL_Surface* textSurface = TTF_RenderText_Solid(font->loadedFont, text.c_str(), SDL_Color {color.r, color.g, color.b, color.a });
SDL_Texture* textTexture = SDL_CreateTextureFromSurface(renderer, textSurface);
int width = 0;
int height = 0;
TTF_SizeText(font->loadedFont, text.c_str(), &width, &height);
SDL_Rect textRect;
textRect.x = pos.x;
textRect.y = pos.y;
textRect.w = width;
textRect.h = height;
SDL_RenderCopy(renderer, textTexture, NULL, &textRect);
SDL_DestroyTexture(textTexture);
SDL_FreeSurface(textSurface);
} }
}
void RSDL::renderCurrent() { void RSDL::preDraw() {}
SDL_UpdateWindowSurface(window); void RSDL::postDraw() {}
SDL_RenderPresent(renderer);
void RSDL::update() {
SDL_Event event;
while(SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) keepOpen = false;
} }
}
void RSDL::drawText(Resource* resource, std::string text, IntVec2 pos, Color color) { void RSDL::setWindowTitle(std::string title) {
if (Font* font = (Font*)resource) { SDL_SetWindowTitle(window, title.c_str());
SDL_Surface* textSurface = TTF_RenderText_Solid(font->loadedFont, text.c_str(), SDL_Color {color.r, color.g, color.b, color.a });
SDL_Texture* textTexture = SDL_CreateTextureFromSurface(renderer, textSurface);
int width = 0;
int height = 0;
TTF_SizeText(font->loadedFont, text.c_str(), &width, &height);
SDL_Rect textRect;
textRect.x = pos.x;
textRect.y = pos.y;
textRect.w = width;
textRect.h = height;
SDL_RenderCopy(renderer, textTexture, NULL, &textRect);
SDL_DestroyTexture(textTexture);
SDL_FreeSurface(textSurface);
}
}
void RSDL::preDraw() {}
void RSDL::postDraw() {}
void RSDL::update() {
SDL_Event event;
while(SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) keepOpen = false;
}
}
void RSDL::setWindowTitle(std::string title) {}
} }
} }

View file

@ -9,35 +9,33 @@
#include <math/types.hpp> #include <math/types.hpp>
#include <renderer/renderer.hpp> #include <renderer/renderer.hpp>
namespace hibis { namespace hibis::rsdl {
namespace rsdl { /** \class RSDL
/** \class RSDL * Renderer implementation using SDL2 Renderer for the Hibis game engine
* Renderer implementation using SDL2 Renderer for the Hibis game engine */
*/ class RSDL : public Renderer {
class RSDL : public Renderer { public:
public: RSDL(std::string title, IntVec2 size, LoggerCallback callback);
RSDL(std::string title, IntVec2 size, LoggerCallback callback);
~RSDL(); ~RSDL();
void clearScreen(Color col = Color {0, 0, 0, 1}); void clearScreen(Color col = Color {0, 0, 0, 255});
void renderCurrent(); void renderCurrent();
void drawText(Resource* resource, std::string text, IntVec2 pos, Color color); void drawText(Resource* resource, std::string text, IntVec2 pos, Color color);
void preDraw(); void preDraw();
void postDraw(); void postDraw();
void update(); void update();
void setWindowTitle(std::string title); void setWindowTitle(std::string title);
private: private:
SDL_Window* window; SDL_Window* window;
SDL_Renderer* renderer; SDL_Renderer* renderer;
LoggerCallback logger; LoggerCallback logger;
}; };
}
} }

View file

@ -11,6 +11,12 @@
#include <engine/engine.hpp> #include <engine/engine.hpp>
#include <pragmautil.hpp>
#if defined(_MSC_VER) || defined(_MSC_FULL_VER)
WARNING("Please avoid using MSVC in C++ projects utilising std::chrono due to frame timing issues")
#endif
using namespace hibis; using namespace hibis;
using namespace hibis::rsdl; using namespace hibis::rsdl;
@ -34,7 +40,7 @@ void logger(LoggingSeverity severity, std::string message) {
break; break;
} }
std::cout << fmt::format("[{}]: {}", severity, message) << std::endl; std::cout << fmt::format("[{}]: {}", sevString, message) << std::endl;
} }
int main() { int main() {