Switch to SDL2_ttf for text in rsdl renderer

This commit is contained in:
Tulpen 2023-05-24 18:24:37 +01:00
parent 5ad032ba68
commit c4f097d6b1
9 changed files with 79 additions and 80 deletions

View file

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

View file

@ -10,9 +10,6 @@ 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;
@ -22,16 +19,10 @@ class Engine {
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();
}
@ -68,9 +59,6 @@ class Engine {
}
}
private FTSupport freetypeSupport;
public FT_Library freetypeLib;
private Renderer renderer;
private StopWatch watch;
private float previousProcessTick;

View file

@ -13,11 +13,16 @@ struct Point2D {
float x, y;
}
/// Defines a given area with a width and height at the given point.
/// Defines a given area.
struct Rect {
float x, y, w, h;
}
/// Integer variation of Rect.
struct IntRect {
int x, y, w, h;
}
/// X and Y values using floats.
struct Vec2 {
float x, y;

View file

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

View file

@ -1,18 +0,0 @@
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,8 +1,9 @@
name "rsdl"
dependency "hibis:core" version=">=0.0.0"
dependency "bindbc-sdl" version="~>1.3.5"
dependency "bindbc-freetype" version="~>1.0.5"
versions "SDL_2_26" "SDL_TTF_2_20"
libs "SDL2" "SDL2_ttf"
targetType "library"
targetName "hibis_rsdl"
# Source paths so this can compile properly
sourcePaths "./" "../../core"
sourcePaths "./" "../../core"

View file

@ -1,28 +1,33 @@
module hibis_rsdl;
module hibis_rsdl.rsdl;
import hibis.resources.resource;
import hibis.callback;
import hibis.logging.types;
import hibis_rsdl.resources.font;
import bindbc.sdl;
import bindbc.freetype.bind;
import bindbc.freetype.bind.ftbitmap;
import sdl_ttf;
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
*/
class RSDL : Renderer {
this(string title, IntVec2 size) {
this(string title, IntVec2 size, LoggerCallback callback) {
this.logger = callback;
const SDLSupport ret = loadSDL();
if(ret != sdlSupport) {
throw new Exception("Couldn't load SDL library!");
}
const SDLTTFSupport ttf = loadSDLTTF();
SDL_Init(SDL_INIT_VIDEO);
// Create window. `title` is cast to a char* here as toStringz returns an immutable char* (causing an error)
@ -31,6 +36,7 @@ class RSDL : Renderer {
if (window is null) {
string error = format("Couldn't create window! what: %d", SDL_GetError());
SDL_Quit();
throw new Exception(error);
}
@ -38,14 +44,28 @@ class RSDL : Renderer {
if (renderer is null) {
string error = format("Couldn't create renderer! what: %d", SDL_GetError());
SDL_DestroyWindow(window);
SDL_Quit();
throw new Exception(error);
}
if (TTF_Init() != 0) {
logger(LoggingSeverity.Fatal, format("Couldn't load SDL_TTF! what: %d", TTF_GetError()));
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
TTF_Quit();
throw new Exception("");
}
}
~this() {
TTF_Quit();
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
unloadSDL();
}
override void clearScreen(Color col = Color(0, 0, 0, 1)) {
@ -58,21 +78,21 @@ class RSDL : 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);
override void drawText(Resource resource, string text, IntRect rect, Color color) {
if (Font font = cast(Font)resource) {
SDL_Surface* textSurface = TTF_RenderText_Solid(font.loadedFont, cast(const(char)*)toStringz(text), SDL_Color(color.r, color.g, color.b, color.a));
SDL_Texture* textTexture = SDL_CreateTextureFromSurface(renderer, textSurface);
drawBitmap(font.face.glyph.bitmap, size, dupPos.x + font.face.glyph.bitmap_left, dupPos.y - font.face.glyph.bitmap_top);
SDL_Rect textRect;
textRect.x = rect.x;
textRect.y = rect.y;
textRect.w = rect.w;
textRect.h = rect.h;
dupPos.x += size;
}
SDL_RenderCopy(renderer, textTexture, null, &textRect);
SDL_DestroyTexture(textTexture);
SDL_FreeSurface(textSurface);
}
}
@ -89,25 +109,8 @@ 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;
private LoggerCallback logger;
}

View file

@ -0,0 +1,21 @@
module hibis_rsdl.resources.font;
import hibis.resources.resource;
import sdl_ttf;
import std.string : toStringz;
import std.stdio;
class Font : Resource {
this(string path, uint size) {
const char* nPath = cast(const(char)*)toStringz(path);
loadedFont = TTF_OpenFont(nPath, size);
writeln("Loaded font");
}
~this() {
TTF_CloseFont(loadedFont);
}
public TTF_Font* loadedFont;
}

View file

@ -5,10 +5,10 @@ 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;
import hibis_rsdl.rsdl;
import hibis_rsdl.resources.font;
import core.thread;
@ -17,12 +17,12 @@ void logger(LoggingSeverity severity, string message) {
}
void main() {
Renderer renderer = new RSDL("test", IntVec2(800, 600));
Renderer renderer = new RSDL("test", IntVec2(800, 600), &logger);
Engine engine = new Engine(renderer, &logger);
version(windows) {
Font font = new Font(engine.freetypeLib, "C:\\Windows\\Fonts\\Arial.ttf");
Font font = new Font("C:\\Windows\\Fonts\\Arial.ttf", 16);
} else {
Font font = new Font(engine.freetypeLib, "/usr/share/fonts/noto/NotoSans-Light.ttf");
Font font = new Font("/usr/share/fonts/noto/NotoSans-Light.ttf", 16);
}
ubyte red = 0;
bool increase = true;
@ -40,7 +40,7 @@ void main() {
// Clear screen then sleep for ~16ms
renderer.clearScreen(Color(red, 0, 0, 255));
renderer.drawText(font, "TEST", 16, IntVec2(0, 0));
renderer.drawText(font, "TEST", IntRect(0, 0, 64, 64), Color(255, 255, 255, 255));
engine.drawNodes();
renderer.renderCurrent();