Switch to SDL2_ttf for text in rsdl renderer
This commit is contained in:
parent
5ad032ba68
commit
c4f097d6b1
|
@ -1,5 +1,4 @@
|
||||||
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"
|
||||||
|
|
|
@ -10,9 +10,6 @@ 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;
|
||||||
|
@ -22,16 +19,10 @@ class Engine {
|
||||||
|
|
||||||
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,9 +59,6 @@ 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;
|
||||||
|
|
|
@ -13,11 +13,16 @@ struct Point2D {
|
||||||
float x, y;
|
float x, y;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Defines a given area with a width and height at the given point.
|
/// Defines a given area.
|
||||||
struct Rect {
|
struct Rect {
|
||||||
float x, y, w, h;
|
float x, y, w, h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Integer variation of Rect.
|
||||||
|
struct IntRect {
|
||||||
|
int x, y, w, h;
|
||||||
|
}
|
||||||
|
|
||||||
/// X and Y values using floats.
|
/// X and Y values using floats.
|
||||||
struct Vec2 {
|
struct Vec2 {
|
||||||
float x, y;
|
float x, y;
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
module hibis.renderer.renderer;
|
module hibis.renderer.renderer;
|
||||||
|
|
||||||
import hibis.math.types;
|
import hibis.math.types;
|
||||||
import hibis.resources.font;
|
import hibis.resources.resource;
|
||||||
|
|
||||||
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);
|
void drawText(Resource resource, string text, IntRect rect, Color color);
|
||||||
|
|
||||||
// Pre and Post draw
|
// Pre and Post draw
|
||||||
void preDraw();
|
void preDraw();
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -1,7 +1,8 @@
|
||||||
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"
|
versions "SDL_2_26" "SDL_TTF_2_20"
|
||||||
|
libs "SDL2" "SDL2_ttf"
|
||||||
targetType "library"
|
targetType "library"
|
||||||
targetName "hibis_rsdl"
|
targetName "hibis_rsdl"
|
||||||
# Source paths so this can compile properly
|
# Source paths so this can compile properly
|
||||||
|
|
|
@ -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.sdl;
|
||||||
import bindbc.freetype.bind;
|
import sdl_ttf;
|
||||||
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.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
|
||||||
*/
|
*/
|
||||||
class RSDL : Renderer {
|
class RSDL : Renderer {
|
||||||
this(string title, IntVec2 size) {
|
this(string title, IntVec2 size, LoggerCallback callback) {
|
||||||
|
this.logger = callback;
|
||||||
const SDLSupport ret = loadSDL();
|
const SDLSupport ret = loadSDL();
|
||||||
if(ret != sdlSupport) {
|
if(ret != sdlSupport) {
|
||||||
throw new Exception("Couldn't load SDL library!");
|
throw new Exception("Couldn't load SDL library!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const SDLTTFSupport ttf = loadSDLTTF();
|
||||||
|
|
||||||
SDL_Init(SDL_INIT_VIDEO);
|
SDL_Init(SDL_INIT_VIDEO);
|
||||||
|
|
||||||
// Create window. `title` is cast to a char* here as toStringz returns an immutable char* (causing an error)
|
// 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) {
|
if (window is null) {
|
||||||
string error = format("Couldn't create window! what: %d", SDL_GetError());
|
string error = format("Couldn't create window! what: %d", SDL_GetError());
|
||||||
|
SDL_Quit();
|
||||||
throw new Exception(error);
|
throw new Exception(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,14 +44,28 @@ class RSDL : Renderer {
|
||||||
|
|
||||||
if (renderer is null) {
|
if (renderer is null) {
|
||||||
string error = format("Couldn't create renderer! what: %d", SDL_GetError());
|
string error = format("Couldn't create renderer! what: %d", SDL_GetError());
|
||||||
|
SDL_DestroyWindow(window);
|
||||||
|
SDL_Quit();
|
||||||
throw new Exception(error);
|
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() {
|
~this() {
|
||||||
|
TTF_Quit();
|
||||||
SDL_DestroyRenderer(renderer);
|
SDL_DestroyRenderer(renderer);
|
||||||
SDL_DestroyWindow(window);
|
SDL_DestroyWindow(window);
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
|
|
||||||
|
unloadSDL();
|
||||||
}
|
}
|
||||||
|
|
||||||
override void clearScreen(Color col = Color(0, 0, 0, 1)) {
|
override void clearScreen(Color col = Color(0, 0, 0, 1)) {
|
||||||
|
@ -58,21 +78,21 @@ class RSDL : Renderer {
|
||||||
SDL_RenderPresent(renderer);
|
SDL_RenderPresent(renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
override void drawText(Font font, string text, int size, IntVec2 pos) {
|
override void drawText(Resource resource, string text, IntRect rect, Color color) {
|
||||||
IntVec2 dupPos = { x: pos.x, y: pos.y };
|
if (Font font = cast(Font)resource) {
|
||||||
dupPos.y += size-4;
|
SDL_Surface* textSurface = TTF_RenderText_Solid(font.loadedFont, cast(const(char)*)toStringz(text), SDL_Color(color.r, color.g, color.b, color.a));
|
||||||
FT_Set_Pixel_Sizes(font.face, size, size);
|
SDL_Texture* textTexture = SDL_CreateTextureFromSurface(renderer, textSurface);
|
||||||
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);
|
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) {}
|
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;
|
||||||
|
|
||||||
|
private LoggerCallback logger;
|
||||||
}
|
}
|
21
renderer/rsdl/source/resources/font.d
Normal file
21
renderer/rsdl/source/resources/font.d
Normal 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;
|
||||||
|
}
|
|
@ -5,10 +5,10 @@ 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.rsdl;
|
||||||
|
import hibis_rsdl.resources.font;
|
||||||
|
|
||||||
import core.thread;
|
import core.thread;
|
||||||
|
|
||||||
|
@ -17,12 +17,12 @@ 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), &logger);
|
||||||
Engine engine = new Engine(renderer, &logger);
|
Engine engine = new Engine(renderer, &logger);
|
||||||
version(windows) {
|
version(windows) {
|
||||||
Font font = new Font(engine.freetypeLib, "C:\\Windows\\Fonts\\Arial.ttf");
|
Font font = new Font("C:\\Windows\\Fonts\\Arial.ttf", 16);
|
||||||
} else {
|
} 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;
|
ubyte red = 0;
|
||||||
bool increase = true;
|
bool increase = true;
|
||||||
|
@ -40,7 +40,7 @@ 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));
|
renderer.drawText(font, "TEST", IntRect(0, 0, 64, 64), Color(255, 255, 255, 255));
|
||||||
|
|
||||||
engine.drawNodes();
|
engine.drawNodes();
|
||||||
renderer.renderCurrent();
|
renderer.renderCurrent();
|
||||||
|
|
Loading…
Reference in a new issue