Switch to SDL2_ttf for text in rsdl renderer
This commit is contained in:
parent
5ad032ba68
commit
c4f097d6b1
|
@ -1,5 +1,4 @@
|
|||
name "core"
|
||||
license "LGPL-3.0"
|
||||
dependency "bindbc-freetype" version="~>1.0.5"
|
||||
targetType "library"
|
||||
targetName "hibiscore"
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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,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"
|
||||
|
|
|
@ -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;
|
||||
}
|
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.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();
|
||||
|
|
Loading…
Reference in a new issue