diff --git a/core/dub.sdl b/core/dub.sdl index e59dc06..2f3c0c9 100644 --- a/core/dub.sdl +++ b/core/dub.sdl @@ -1,4 +1,5 @@ name "core" license "LGPL-3.0" +dependency "bindbc-freetype" version="~>1.0.5" targetType "library" -targetName "hibiscore" \ No newline at end of file +targetName "hibiscore" diff --git a/core/source/callback.d b/core/source/callback.d index cd163e0..423de85 100644 --- a/core/source/callback.d +++ b/core/source/callback.d @@ -2,4 +2,4 @@ module hibis.callback; import hibis.logging.types; -alias LoggerCallback = void function(LoggingSeverity severity, string message); \ No newline at end of file +alias LoggerCallback = void function(LoggingSeverity severity, string message); diff --git a/core/source/core/engine.d b/core/source/core/engine.d index 6316da1..ee49a85 100644 --- a/core/source/core/engine.d +++ b/core/source/core/engine.d @@ -10,6 +10,9 @@ import std.datetime.stopwatch; import std.stdio; import std.format; +import bindbc.freetype; +import bindbc.freetype.bind; + class Engine { this(Renderer renderer, LoggerCallback logger) { this.renderer = renderer; @@ -18,10 +21,17 @@ class Engine { previousPhysicsProcessTick = 0.00001f; watch.start(); + + this.loggerCallback(LoggingSeverity.Information, "Loading FreeType..."); + + freetypeSupport = loadFreeType(); + FT_Init_FreeType(&freetypeLib); + this.loggerCallback(LoggingSeverity.Information, "Started Hibis!"); } ~this() { + FT_Done_FreeType(freetypeLib); watch.stop(); } @@ -58,6 +68,9 @@ class Engine { } } + private FTSupport freetypeSupport; + public FT_Library freetypeLib; + private Renderer renderer; private StopWatch watch; private float previousProcessTick; diff --git a/core/source/graphics/drawable.d b/core/source/graphics/drawable.d index 4a621ab..899fb0d 100644 --- a/core/source/graphics/drawable.d +++ b/core/source/graphics/drawable.d @@ -2,5 +2,5 @@ module hibis.graphics.drawable; import hibis.renderer.renderer; abstract class Drawable { - void draw(Renderer* renderer); + public void draw(Renderer* renderer); } \ No newline at end of file diff --git a/core/source/logging/types.d b/core/source/logging/types.d index ea6169a..317823c 100644 --- a/core/source/logging/types.d +++ b/core/source/logging/types.d @@ -1,6 +1,6 @@ module hibis.logging.types; -enum LoggingSeverity { +enum LoggingSeverity : ubyte { Message = 0, Information, Warning, diff --git a/core/source/renderer/renderer.d b/core/source/renderer/renderer.d index b8957ee..ed19eec 100644 --- a/core/source/renderer/renderer.d +++ b/core/source/renderer/renderer.d @@ -1,12 +1,15 @@ module hibis.renderer.renderer; import hibis.math.types; +import hibis.resources.font; abstract class Renderer { // Draw void clearScreen(Color col); void renderCurrent(); + void drawText(Font font, string text, int size, IntVec2 pos); + // Pre and Post draw void preDraw(); void postDraw(); diff --git a/core/source/resources/font.d b/core/source/resources/font.d new file mode 100644 index 0000000..aaf793f --- /dev/null +++ b/core/source/resources/font.d @@ -0,0 +1,18 @@ +module hibis.resources.font; + +import hibis.resources.resource; +import bindbc.freetype.bind; + +import std.string : toStringz; + +class Font : Resource { + this(FT_Library freetypeLibrary, string path) { + FT_New_Face(freetypeLibrary, cast(char*)toStringz(path), 0, &face); + } + + ~this() { + FT_Done_Face(face); + } + + public FT_Face face; +} \ No newline at end of file diff --git a/renderer/rsdl/dub.sdl b/renderer/rsdl/dub.sdl index 0a6abe0..f729f4d 100644 --- a/renderer/rsdl/dub.sdl +++ b/renderer/rsdl/dub.sdl @@ -1,6 +1,7 @@ name "rsdl" dependency "hibis:core" version=">=0.0.0" dependency "bindbc-sdl" version="~>1.3.5" +dependency "bindbc-freetype" version="~>1.0.5" targetType "library" targetName "hibis_rsdl" # Source paths so this can compile properly diff --git a/renderer/rsdl/source/hibis_rsdl.d b/renderer/rsdl/source/hibis_rsdl.d index 631eb25..0d42b12 100644 --- a/renderer/rsdl/source/hibis_rsdl.d +++ b/renderer/rsdl/source/hibis_rsdl.d @@ -1,12 +1,17 @@ module hibis_rsdl; import bindbc.sdl; +import bindbc.freetype.bind; +import bindbc.freetype.bind.ftbitmap; import hibis.renderer.renderer; +import hibis.resources.font; import hibis.math.types; import std.exception; import std.format; +import std.stdio; import std.string : toStringz; +import core.stdcpp.vector; /** \class RSDL * Renderer implementation using SDL2 Renderer for the Hibis game engine @@ -49,9 +54,28 @@ class RSDL : Renderer { } override void renderCurrent() { + SDL_UpdateWindowSurface(window); SDL_RenderPresent(renderer); } + override void drawText(Font font, string text, int size, IntVec2 pos) { + IntVec2 dupPos = { x: pos.x, y: pos.y }; + dupPos.y += size-4; + FT_Set_Pixel_Sizes(font.face, size, size); + for (int character = 0; character < text.length; character++) { + if (text[character] == '\n') { + dupPos.x = pos.x; + dupPos.y += size; + } else { + FT_Load_Char(font.face, text[character], FT_LOAD_RENDER); + + drawBitmap(font.face.glyph.bitmap, size, dupPos.x + font.face.glyph.bitmap_left, dupPos.y - font.face.glyph.bitmap_top); + + dupPos.x += size; + } + } + } + override void preDraw() {} override void postDraw() {} @@ -65,6 +89,25 @@ class RSDL : Renderer { override void setWindowTitle(string title) {} + private void drawBitmap(FT_Bitmap bitmap, int size, int x, int y) { + SDL_Surface* glyph = SDL_CreateRGBSurfaceFrom(bitmap.buffer, bitmap.width, bitmap.rows, 8, bitmap.pitch, 0, 0, 0, 0xFF); + + SDL_SetSurfaceBlendMode(glyph, 0); + + SDL_Color[256] colors; + for (int i = 0; i < 256; i++) { + ubyte newC = cast(ubyte)i; + colors[i].r = colors[i].g = colors[i].b = newC; + } + SDL_SetPaletteColors(glyph.format.palette, cast(const(SDL_Color)*)colors, 0, 256); + + SDL_Rect dest = { x, y, size, size}; + SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, glyph); + SDL_RenderCopy(renderer, texture, null, &dest); + SDL_DestroyTexture(texture); + SDL_FreeSurface(glyph); + } + private SDL_Window* window; private SDL_Renderer* renderer; } \ No newline at end of file diff --git a/test/source/app.d b/test/source/app.d index 96125d8..479a8ed 100644 --- a/test/source/app.d +++ b/test/source/app.d @@ -5,6 +5,7 @@ import std.conv; import hibis.core.engine; import hibis.math.types; import hibis.renderer.renderer; +import hibis.resources.font; import hibis.logging.types; import hibis.callback; import hibis_rsdl; @@ -18,7 +19,11 @@ void logger(LoggingSeverity severity, string message) { void main() { Renderer renderer = new RSDL("test", IntVec2(800, 600)); Engine engine = new Engine(renderer, &logger); - + version(windows) { + Font font = new Font(engine.freetypeLib, "C:\\Windows\\Fonts\\Arial.ttf"); + } else { + Font font = new Font(engine.freetypeLib, "/usr/share/fonts/noto/NotoSans-Light.ttf"); + } ubyte red = 0; bool increase = true; @@ -35,10 +40,12 @@ void main() { // Clear screen then sleep for ~16ms renderer.clearScreen(Color(red, 0, 0, 255)); + renderer.drawText(font, "TEST", 16, IntVec2(0, 0)); engine.drawNodes(); renderer.renderCurrent(); renderer.update(); Thread.sleep(16.msecs); } + destroy(font); }