Quite buggy text drawing via FreeType + SDL2

This commit is contained in:
Tulpen 2023-05-23 21:12:22 +01:00
parent cf55551ad6
commit 5ad032ba68
10 changed files with 91 additions and 5 deletions

View file

@ -1,4 +1,5 @@
name "core" name "core"
license "LGPL-3.0" license "LGPL-3.0"
dependency "bindbc-freetype" version="~>1.0.5"
targetType "library" targetType "library"
targetName "hibiscore" targetName "hibiscore"

View file

@ -10,6 +10,9 @@ import std.datetime.stopwatch;
import std.stdio; import std.stdio;
import std.format; import std.format;
import bindbc.freetype;
import bindbc.freetype.bind;
class Engine { class Engine {
this(Renderer renderer, LoggerCallback logger) { this(Renderer renderer, LoggerCallback logger) {
this.renderer = renderer; this.renderer = renderer;
@ -18,10 +21,17 @@ class Engine {
previousPhysicsProcessTick = 0.00001f; previousPhysicsProcessTick = 0.00001f;
watch.start(); watch.start();
this.loggerCallback(LoggingSeverity.Information, "Loading FreeType...");
freetypeSupport = loadFreeType();
FT_Init_FreeType(&freetypeLib);
this.loggerCallback(LoggingSeverity.Information, "Started Hibis!"); this.loggerCallback(LoggingSeverity.Information, "Started Hibis!");
} }
~this() { ~this() {
FT_Done_FreeType(freetypeLib);
watch.stop(); watch.stop();
} }
@ -58,6 +68,9 @@ class Engine {
} }
} }
private FTSupport freetypeSupport;
public FT_Library freetypeLib;
private Renderer renderer; private Renderer renderer;
private StopWatch watch; private StopWatch watch;
private float previousProcessTick; private float previousProcessTick;

View file

@ -2,5 +2,5 @@ module hibis.graphics.drawable;
import hibis.renderer.renderer; import hibis.renderer.renderer;
abstract class Drawable { abstract class Drawable {
void draw(Renderer* renderer); public void draw(Renderer* renderer);
} }

View file

@ -1,6 +1,6 @@
module hibis.logging.types; module hibis.logging.types;
enum LoggingSeverity { enum LoggingSeverity : ubyte {
Message = 0, Message = 0,
Information, Information,
Warning, Warning,

View file

@ -1,12 +1,15 @@
module hibis.renderer.renderer; module hibis.renderer.renderer;
import hibis.math.types; import hibis.math.types;
import hibis.resources.font;
abstract class Renderer { abstract class Renderer {
// Draw // Draw
void clearScreen(Color col); void clearScreen(Color col);
void renderCurrent(); void renderCurrent();
void drawText(Font font, string text, int size, IntVec2 pos);
// Pre and Post draw // Pre and Post draw
void preDraw(); void preDraw();
void postDraw(); void postDraw();

View file

@ -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;
}

View file

@ -1,6 +1,7 @@
name "rsdl" name "rsdl"
dependency "hibis:core" version=">=0.0.0" dependency "hibis:core" version=">=0.0.0"
dependency "bindbc-sdl" version="~>1.3.5" dependency "bindbc-sdl" version="~>1.3.5"
dependency "bindbc-freetype" version="~>1.0.5"
targetType "library" targetType "library"
targetName "hibis_rsdl" targetName "hibis_rsdl"
# Source paths so this can compile properly # Source paths so this can compile properly

View file

@ -1,12 +1,17 @@
module hibis_rsdl; module hibis_rsdl;
import bindbc.sdl; import bindbc.sdl;
import bindbc.freetype.bind;
import bindbc.freetype.bind.ftbitmap;
import hibis.renderer.renderer; import hibis.renderer.renderer;
import hibis.resources.font;
import hibis.math.types; import hibis.math.types;
import std.exception; import std.exception;
import std.format; import std.format;
import std.stdio;
import std.string : toStringz; import std.string : toStringz;
import core.stdcpp.vector;
/** \class RSDL /** \class RSDL
* Renderer implementation using SDL2 Renderer for the Hibis game engine * Renderer implementation using SDL2 Renderer for the Hibis game engine
@ -49,9 +54,28 @@ class RSDL : Renderer {
} }
override void renderCurrent() { override void renderCurrent() {
SDL_UpdateWindowSurface(window);
SDL_RenderPresent(renderer); 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 preDraw() {}
override void postDraw() {} override void postDraw() {}
@ -65,6 +89,25 @@ class RSDL : Renderer {
override void setWindowTitle(string title) {} 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_Window* window;
private SDL_Renderer* renderer; private SDL_Renderer* renderer;
} }

View file

@ -5,6 +5,7 @@ import std.conv;
import hibis.core.engine; import hibis.core.engine;
import hibis.math.types; import hibis.math.types;
import hibis.renderer.renderer; import hibis.renderer.renderer;
import hibis.resources.font;
import hibis.logging.types; import hibis.logging.types;
import hibis.callback; import hibis.callback;
import hibis_rsdl; import hibis_rsdl;
@ -18,7 +19,11 @@ void logger(LoggingSeverity severity, string message) {
void main() { void main() {
Renderer renderer = new RSDL("test", IntVec2(800, 600)); Renderer renderer = new RSDL("test", IntVec2(800, 600));
Engine engine = new Engine(renderer, &logger); 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; ubyte red = 0;
bool increase = true; bool increase = true;
@ -35,10 +40,12 @@ void main() {
// Clear screen then sleep for ~16ms // Clear screen then sleep for ~16ms
renderer.clearScreen(Color(red, 0, 0, 255)); renderer.clearScreen(Color(red, 0, 0, 255));
renderer.drawText(font, "TEST", 16, IntVec2(0, 0));
engine.drawNodes(); engine.drawNodes();
renderer.renderCurrent(); renderer.renderCurrent();
renderer.update(); renderer.update();
Thread.sleep(16.msecs); Thread.sleep(16.msecs);
} }
destroy(font);
} }