Added True Type fonts

This commit is contained in:
2021-05-23 10:53:00 -07:00
parent 98814982de
commit b0dce455f0
26 changed files with 575 additions and 167 deletions

View File

@ -8,13 +8,14 @@
#include "camera.h"
void cameraLookAt(camera_t *camera,
float x, float y, float z, float targetX, float targetY, float targetZ
float x, float y, float z,
float targetX, float targetY, float targetZ
) {
glm_mat4_identity(camera->view);
glm_lookat(
(vec3){ x, y, z },
(vec3){ targetX, targetY, targetZ },
(vec3){ 0, 1, 0 },
(vec3){ 0,1,0 },
camera->view
);
}
@ -27,7 +28,7 @@ void cameraLook(camera_t *camera,
glm_look(
(vec3){ x, y, z },
(vec3){ pitch, yaw, roll },
(vec3){ 0, 1, 0 },
(vec3){ 0,1,0 },
camera->view
);
}

View File

@ -19,7 +19,8 @@
* @param targetZ The Target Z position in world space of the camera.
*/
void cameraLookAt(camera_t *camera,
float x, float y, float z, float targetX, float targetY, float targetZ
float x, float y, float z,
float targetX, float targetY, float targetZ
);
/**

View File

@ -0,0 +1,116 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "bitmapfont.h"
tilesetdiv_t * bitmapFontGetCharacterDivision(tileset_t *tileset, char character) {
int32_t i = ((int32_t)character) - BITMAP_FONT_CHAR_START;
return tileset->divisions + i;
}
bitmapfontmeasure_t bitmapFontMeasure(char *string, float charWidth, float charHeight) {
int32_t i;
float x, y;
char c;
bitmapfontmeasure_t measure = {
.height = 0, .lines = 1, .width = 0
};
i = 0;
y = 0;
x = 0;
while(true) {
c = string[i];
if(c == '\0') break;
i++;
if(c == '\n') {
measure.width = mathMax(x, measure.width);
x = 0;
y += charHeight;
measure.lines++;
continue;
} else if(c == ' ') {
x += charWidth;
continue;
}
x += charWidth;
}
measure.width = mathMax(x, measure.width);
measure.height = y + charHeight;
return measure;
}
bitmapfontmeasure_t bitmapFontSpriteBatchBuffer(
spritebatch_t *batch, tileset_t *tileset,
char *string, float x, float y, float z, float charWidth, float charHeight
) {
int32_t i;
char c;
tilesetdiv_t *div;
float cx, cy;
bitmapfontmeasure_t measure;
// Detect char dimensions
if(charWidth == -1) charWidth = tileset->divX * (charHeight / tileset->divY);
if(charHeight == -1) charHeight = tileset->divY * (charWidth / tileset->divX);
// Position the text.
if(x == BITMAP_FONT_CENTER_X ||
y == BITMAP_FONT_CENTER_Y ||
x == BITMAP_FONT_RIGHT_X
) {
measure = bitmapFontMeasure(string, charWidth, charHeight);
if(x == BITMAP_FONT_CENTER_X) {
x = -(measure.width/2);
} else if(x == BITMAP_FONT_RIGHT_X) {
x = -measure.width;
}
if(y == BITMAP_FONT_CENTER_Y) y = -(measure.height/2);
}
// Begin buffering the sprite batch
measure.width = 0;
measure.height = 0;
measure.lines = 1;
i = 0;
cx = x, cy = y;
while(true) {
c = string[i];
if(c == '\0') break;
i++;
// Special chars
if(c == '\n') {
measure.width = mathMax(cx-x, measure.width);
cx = x;
cy += charHeight;
measure.lines++;
continue;
} else if(c == ' ') {
cx += charWidth;
continue;
}
div = bitmapFontGetCharacterDivision(tileset, c);
spriteBatchQuad(batch, -1,
cx, cy, z, charWidth, charHeight,
div->x0, div->y1, div->x1, div->y0
);
cx += charWidth;
}
measure.width = mathMax(cx-x, measure.width);
measure.height = cy-y + charHeight;
return measure;
}

View File

@ -0,0 +1,47 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include <dawn/dawn.h>
#include "../spritebatch.h"
/**
* Get the division for a given character.
*
* @param tileset Tileset to get the division from.
* @param character Character to get the division for.
* @return The division from the tileset for the character.
*/
tilesetdiv_t * bitmapFontGetCharacterDivision(tileset_t *tileset, char character);
/**
* Measures a string's fully rendered size.
*
* @param string The string to measure
* @param charWidth The width of each character.
* @param charHeight The height of each character.
* @return The measured string.
*/
bitmapfontmeasure_t bitmapFontMeasure(char *string, float charWidth, float charHeight);
/**
* Renders a set of font characters to the sprite. Coordinates are anchored to
* the top left (0,0) origin.
*
* @param batch Sprite Batch to render to.
* @param tileset Tileset for the font.
* @param string String to render.
* @param x Position in X space.
* @param y Position in Y space.
* @param z Position in Z space.
* @param charWidth Width of each character. Set to -1 to use the height ratio.
* @param charHeight Height of each character. Set to -1 to be the width ratio.
* @returns The string measurement.
*/
bitmapfontmeasure_t bitmapFontSpriteBatchBuffer(spritebatch_t *batch, tileset_t *tileset,
char *string, float x, float y, float z, float charWidth, float charHeight
);

View File

@ -7,109 +7,137 @@
#include "font.h"
tilesetdiv_t * fontGetCharacterDivision(tileset_t *tileset, char character) {
int32_t i = ((int32_t)character) - FONT_CHAR_START;
return tileset->divisions + i;
// Due to some compiler bullshit, this is here.
#ifndef STB_TRUETYPE_IMPLEMENTATION
#define STB_TRUETYPE_IMPLEMENTATION
#include <stb_truetype.h>
#endif
void fontInit(font_t *font, char *data, float size) {
int32_t i, s;
s = FONT_TEXTURE_WIDTH * FONT_TEXTURE_HEIGHT;
uint8_t *bitmapData = malloc(sizeof(uint8_t) * s);
pixel_t *pixels = malloc(sizeof(pixel_t) * s);
font->size = size;
// STBTT Loads fonts as single channel values only.
stbtt_BakeFontBitmap(
data, 0, size, bitmapData,
FONT_TEXTURE_WIDTH, FONT_TEXTURE_HEIGHT,
FONT_FIRST_CHAR, FONT_NUM_CHARS,
font->characterData
);
for(i = 0; i < FONT_TEXTURE_WIDTH * FONT_TEXTURE_HEIGHT; i++) {
pixels[i].r = 0xFF;
pixels[i].g = 0xFF;
pixels[i].b = 0xFF;
pixels[i].a = bitmapData[i];
}
textureInit(&font->texture, FONT_TEXTURE_WIDTH, FONT_TEXTURE_HEIGHT, pixels);
free(bitmapData);
free(pixels);
}
fontmeasure_t fontMeasure(char *string, float charWidth, float charHeight) {
int32_t i;
fonttextinfo_t fontGetTextInfo(font_t *font, char *text) {
float x, y;
char c;
fontmeasure_t measure = {
.height = 0, .lines = 1, .width = 0
int32_t i;
fonttextinfo_t info = {
.length = 0,
.realChars = 0,
.lineHeight = FONT_LINE_HEIGHT * font->size,
.spaceSize = font->size * FONT_SPACE_SIZE
};
// Count how many "real characters" are in the string.
i = 0;
y = 0;
x = 0;
while(c = text[i++]) {
info.length++;
if(c == FONT_SPACE) continue;
if(c == FONT_NEWLINE) continue;
info.realChars++;
}
while(true) {
c = string[i];
if(c == '\0') break;
i++;
if(c == '\n') {
measure.width = mathMax(x, measure.width);
x = 0;
y += charHeight;
measure.lines++;
continue;
} else if(c == ' ') {
x += charWidth;
return info;
}
fontmeasure_t * fontTextMeasure(font_t *font,char *text,fonttextinfo_t *info) {
int32_t i, j;
char c;
float x, y;
stbtt_aligned_quad *quad;
fontmeasure_t *measure;
measure = malloc(sizeof(fontmeasure_t));
measure->quads = malloc(sizeof(stbtt_aligned_quad) * info->realChars);
x = 0;
y = FONT_INITIAL_LINE * font->size;
i = 0, j = 0;
while(c = text[i++]) {
if(c == FONT_SPACE) {
x += info->spaceSize;
continue;
}
x += charWidth;
if(c == FONT_NEWLINE) {
y += info->lineHeight;
x = 0;
continue;
}
// Calculate the quad of the character, store into the array.
quad = measure->quads + j;
stbtt_GetBakedQuad(font->characterData,
FONT_TEXTURE_WIDTH, FONT_TEXTURE_HEIGHT, ((int32_t)c)-FONT_FIRST_CHAR,
&x, &y, quad, FONT_FILL_MODE
);
j++;
}
measure.width = mathMax(x, measure.width);
measure.height = y + charHeight;
return measure;
}
fontmeasure_t fontSpriteBatchBuffer(spritebatch_t *batch, tileset_t *tileset,
char *string, float x, float y, float z, float charWidth, float charHeight
void fontTextMeasureDispose(fontmeasure_t *measure) {
free(measure->quads);
free(measure);
}
void fontTextBufferFromMeasure(font_t *font, primitive_t *primitive, char *text,
fontmeasure_t *measure
) {
int32_t i;
stbtt_aligned_quad *quad;
int32_t i, j;
char c;
tilesetdiv_t *div;
float cx, cy;
fontmeasure_t measure;
// Detect char dimensions
if(charWidth == -1) charWidth = tileset->divX * (charHeight / tileset->divY);
if(charHeight == -1) charHeight = tileset->divY * (charWidth / tileset->divX);
// Position the text.
if(x == FONT_CENTER_X ||
y == FONT_CENTER_Y ||
x == FONT_RIGHT_X
) {
measure = fontMeasure(string, charWidth, charHeight);
if(x == FONT_CENTER_X) {
x = -(measure.width/2);
} else if(x == FONT_RIGHT_X) {
x = -measure.width;
}
if(y == FONT_CENTER_Y) y = -(measure.height/2);
}
// Begin buffering the sprite batch
measure.width = 0;
measure.height = 0;
measure.lines = 1;
i = 0;
cx = x, cy = y;
while(true) {
c = string[i];
if(c == '\0') break;
i++;
// Special chars
if(c == '\n') {
measure.width = mathMax(cx-x, measure.width);
cx = x;
cy += charHeight;
measure.lines++;
continue;
} else if(c == ' ') {
cx += charWidth;
continue;
}
div = fontGetCharacterDivision(tileset, c);
spriteBatchQuad(batch, -1,
cx, cy, z, charWidth, charHeight,
div->x0, div->y1, div->x1, div->y0
i = 0, j = 0;
while(c = text[i++]) {
if(c == FONT_SPACE) continue;
if(c == FONT_NEWLINE) continue;
quad = measure->quads + j;
quadBuffer(primitive, 0,
quad->x0, quad->y0, quad->s0, quad->t0,
quad->x1, quad->y1, quad->s1, quad->t1,
j*QUAD_VERTICE_COUNT, j*QUAD_INDICE_COUNT
);
cx += charWidth;
j++;
}
}
measure.width = mathMax(cx-x, measure.width);
measure.height = cy-y + charHeight;
void fontTextInitFromMeasure(font_t *font, primitive_t *primitive, char *text,
fonttextinfo_t *info, fontmeasure_t *measure
) {
primitiveInit(primitive,
QUAD_VERTICE_COUNT*info->realChars, QUAD_INDICE_COUNT*info->realChars
);
fontTextBufferFromMeasure(font, primitive, text, measure);
}
return measure;
void fontDispose(font_t *font) {
textureDispose(&font->texture);
}

View File

@ -6,42 +6,72 @@
*/
#pragma once
#include <dawn/dawn.h>
#include "../spritebatch.h"
#include "../texture.h"
#include "../primitive.h"
#include "../primitives/quad.h"
/**
* Get the division for a given character.
*
* @param tileset Tileset to get the division from.
* @param character Character to get the division for.
* @return The division from the tileset for the character.
* Initializes Font from raw TTF data.
* @param font Font to initialize
* @param data Data to intialize for.
* @param size Font size to load the font in.
*/
tilesetdiv_t * fontGetCharacterDivision(tileset_t *tileset, char character);
void fontInit(font_t *font, char *data, float size);
/**
* Measures a string's fully rendered size.
*
* @param string The string to measure
* @param charWidth The width of each character.
* @param charHeight The height of each character.
* @return The measured string.
* Generates information about how the given font will render the given text.
* @param font Font to get the information for.
* @param text Text that will be used to render
* @return Some information about how the font will render the text.
*/
fontmeasure_t fontMeasure(char *string, float charWidth, float charHeight);
fonttextinfo_t fontGetTextInfo(font_t *font, char *text);
/**
* Renders a set of font characters to the sprite. Coordinates are anchored to
* the top left (0,0) origin.
* Measures (and calculates the quads for) a text prior to rendering it.
*
* @param batch Sprite Batch to render to.
* @param tileset Tileset for the font.
* @param string String to render.
* @param x Position in X space.
* @param y Position in Y space.
* @param z Position in Z space.
* @param charWidth Width of each character. Set to -1 to use the height ratio.
* @param charHeight Height of each character. Set to -1 to be the width ratio.
* @returns The string measurement.
* @param font Font to use for rendering and measuring
* @param text Text to measure/render.
* @param info Info about the text being rendered / measured.
* @returns Font measurement calculation.
*/
fontmeasure_t fontSpriteBatchBuffer(spritebatch_t *batch, tileset_t *tileset,
char *string, float x, float y, float z, float charWidth, float charHeight
);
fontmeasure_t * fontTextMeasure(font_t *font, char *text, fonttextinfo_t *info);
/**
* Disposes a previously calculated font text measurement.
* @param measure Measurement to dispose.
*/
void fontTextMeasureDispose(fontmeasure_t *measure);
/**
* Buffers the vertices of a font text onto a primitive. Requires some info
* about how the font is meant to render from the text info section.
*
* @param font Font to render.
* @param primitive Primitive to render into.
* @param text Text to render.
* @param measure The precalculated measurement.
*/
void fontTextBufferFromMeasure(font_t *font, primitive_t *primitive, char *text,
fontmeasure_t *measure
);
/**
* Initializes an uninitialized primitive for rendering.
*
* @param font Font to render.
* @param primitive Primitive to render into.
* @param text Text to render.
* @param info Text Info to use while rendering.
* @param measure The pre calcuted font measurement.
*/
void fontTextInitFromMeasure(font_t *font, primitive_t *primitive, char *text,
fonttextinfo_t *info, fontmeasure_t *measure
);
/**
* Clean up a previously loaded font
* @param font Loaded font.
*/
void fontDispose(font_t *Font);

View File

@ -7,6 +7,12 @@
#include "texture.h"
// Due to some compiler bullshit, this is here.
#ifndef STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>
#endif
void textureInit(texture_t *texture, int32_t width, int32_t height,
pixel_t *pixels
) {