rework API for batching
parent
f83323c365
commit
6cbf8d1f8a
|
@ -62,8 +62,8 @@ WELLSPRINGAPI uint32_t Wellspring_LinkedVersion(void);
|
|||
|
||||
/* Type definitions */
|
||||
|
||||
typedef struct Wellspring_Font Wellspring_Font;
|
||||
typedef struct Wellspring_Packer Wellspring_Packer;
|
||||
typedef struct Wellspring_TextBatch Wellspring_TextBatch;
|
||||
|
||||
typedef struct Wellspring_FontRange
|
||||
{
|
||||
|
@ -80,89 +80,113 @@ typedef struct Wellspring_GlyphQuad
|
|||
float x1, y1, s1, t1; // bottom-right;
|
||||
} Wellspring_GlyphQuad;
|
||||
|
||||
typedef struct Wellspring_Color
|
||||
{
|
||||
uint8_t r, g, b, a;
|
||||
} Wellspring_Color;
|
||||
|
||||
typedef struct Wellspring_Vertex
|
||||
{
|
||||
float x, y, z;
|
||||
float u, v;
|
||||
uint8_t r, g, b, a;
|
||||
} Wellspring_Vertex;
|
||||
|
||||
/* API definition */
|
||||
|
||||
WELLSPRINGAPI Wellspring_Font* Wellspring_LoadFont(
|
||||
const uint8_t *fontData, /* can be freed after */
|
||||
uint32_t fontDataLength
|
||||
);
|
||||
|
||||
WELLSPRINGAPI void Wellspring_GetFontMetrics(
|
||||
Wellspring_Font *font,
|
||||
int32_t *pAscent,
|
||||
int32_t *pDescent,
|
||||
int32_t *pLineGap
|
||||
);
|
||||
|
||||
WELLSPRINGAPI int32_t Wellspring_FindGlyphIndex(
|
||||
Wellspring_Font *font,
|
||||
int32_t codepoint
|
||||
);
|
||||
|
||||
WELLSPRINGAPI void Wellspring_GetGlyphMetrics(
|
||||
Wellspring_Font *font,
|
||||
int32_t glyphIndex,
|
||||
int32_t *pAdvance,
|
||||
int32_t *pLeftSideBearing
|
||||
);
|
||||
|
||||
WELLSPRINGAPI int32_t Wellspring_GetGlyphKernAdvance(
|
||||
Wellspring_Font *font,
|
||||
int32_t glyphIndexA,
|
||||
int32_t glyphIndexB
|
||||
);
|
||||
|
||||
WELLSPRINGAPI Wellspring_Packer* Wellspring_CreatePacker(
|
||||
uint8_t *pixels,
|
||||
uint8_t *fontBytes,
|
||||
uint32_t fontBytesLength,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
uint32_t strideInBytes,
|
||||
uint32_t padding
|
||||
uint32_t strideInBytes, /* 0 means the buffer is tightly packed. */
|
||||
uint32_t padding /* A sensible value here is 1 to allow bilinear filtering. */
|
||||
);
|
||||
|
||||
WELLSPRINGAPI uint32_t Wellspring_PackFontRanges(
|
||||
Wellspring_Packer *packer,
|
||||
Wellspring_Font *font,
|
||||
Wellspring_FontRange *ranges,
|
||||
uint32_t numRanges
|
||||
);
|
||||
|
||||
WELLSPRINGAPI uint8_t* Wellspring_GetPixels(
|
||||
Wellspring_Packer *packer
|
||||
/* This data must be uploaded to a texture before you render!
|
||||
* The pixel data also becomes outdated if you call PackFontRanges.
|
||||
* Length is width * height.
|
||||
*/
|
||||
WELLSPRINGAPI void Wellspring_GetPixels(
|
||||
Wellspring_Packer *packer,
|
||||
uint8_t **pData
|
||||
);
|
||||
|
||||
WELLSPRINGAPI uint32_t Wellspring_GetGlyphQuad(
|
||||
/* Batches are not thread-safe, recommend one batch per thread. */
|
||||
WELLSPRINGAPI Wellspring_TextBatch* Wellspring_TextBatchCreate();
|
||||
|
||||
/* Also restarts the batch */
|
||||
WELLSPRINGAPI void Wellspring_TextBatchStart(Wellspring_TextBatch *textBatch);
|
||||
|
||||
WELLSPRINGAPI uint8_t Wellspring_DrawTextBatched(
|
||||
Wellspring_TextBatch *textBatch,
|
||||
Wellspring_Packer *packer,
|
||||
int32_t glyphIndex,
|
||||
Wellspring_GlyphQuad *pGlyphQuad
|
||||
float x,
|
||||
float y,
|
||||
float depth,
|
||||
Wellspring_Color *color,
|
||||
const uint8_t *strBytes,
|
||||
uint32_t strLengthInBytes
|
||||
);
|
||||
|
||||
WELLSPRINGAPI void Wellspring_TextBatchGetBufferLengths(
|
||||
Wellspring_TextBatch *textBatch,
|
||||
uint32_t *pVertexLength,
|
||||
uint32_t *pIndexLength
|
||||
);
|
||||
|
||||
WELLSPRINGAPI void Wellspring_TextBatchGetBuffers(
|
||||
Wellspring_TextBatch *textBatch,
|
||||
Wellspring_Vertex **pVertexBuffer,
|
||||
uint32_t **pIndexBuffer
|
||||
);
|
||||
|
||||
WELLSPRINGAPI void Wellspring_TextBatchDestroy(Wellspring_TextBatch *textBatch);
|
||||
|
||||
WELLSPRINGAPI void Wellspring_DestroyPacker(Wellspring_Packer *packer);
|
||||
WELLSPRINGAPI void Wellspring_DestroyFont(Wellspring_Font *font);
|
||||
|
||||
/* Function defines */
|
||||
|
||||
#ifdef USE_SDL2
|
||||
|
||||
#define Wellspring_malloc SDL_malloc
|
||||
#define Wellspring_realloc SDL_realloc
|
||||
#define Wellspring_free SDL_free
|
||||
#define Wellspring_memcpy SDL_memcpy
|
||||
#define Wellspring_memset SDL_memset
|
||||
#define Wellspring_ifloor(x) ((int) SDL_floorf(x))
|
||||
#define Wellspring_iceil(x) ((int) SDL_ceilf(x))
|
||||
#define Wellspring_sqrt SDL_sqrt
|
||||
#define Wellspring_pow SDL_pow
|
||||
|
||||
/* FIXME: finish these defines */
|
||||
#define Wellspring_fmod SDL_fmod
|
||||
#define Wellspring_cos SDL_cos
|
||||
#define Wellspring_acos SDL_acos
|
||||
#define Wellspring_fabs SDL_fabs
|
||||
#define Wellspring_assert SDL_assert
|
||||
#define Wellspring_strlen SDL_strlen
|
||||
|
||||
#else
|
||||
|
||||
#define Wellspring_malloc malloc
|
||||
#define Wellspring_realloc realloc
|
||||
#define Wellspring_free free
|
||||
#define Wellspring_memcpy memcpy
|
||||
#define Wellspring_ifloor(x) ((int) floor(x))
|
||||
#define Wellspring_iceil(x) ((int) ceil(x))
|
||||
#define Wellspring_sqrt sqrt
|
||||
#define Wellspring_pow pow
|
||||
#define Wellspring_fmod fmod
|
||||
#define Wellspring_cos cos
|
||||
#define Wellspring_acos acos
|
||||
#define Wellspring_fabs fabs
|
||||
#define Wellspring_assert assert
|
||||
#define Wellspring_strlen strlen
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -424,14 +424,17 @@ int main(int arg, char **argv)
|
|||
|
||||
#ifdef STB_TRUETYPE_IMPLEMENTATION
|
||||
// #define your own (u)stbtt_int8/16/32 before including to override this
|
||||
#ifndef stbtt_uint8
|
||||
typedef unsigned char stbtt_uint8;
|
||||
typedef signed char stbtt_int8;
|
||||
typedef unsigned short stbtt_uint16;
|
||||
typedef signed short stbtt_int16;
|
||||
typedef unsigned int stbtt_uint32;
|
||||
typedef signed int stbtt_int32;
|
||||
#endif
|
||||
/* this is a lie - C99 cannot check the existence of or override typedefs -cosmonaut */
|
||||
/*
|
||||
* #ifndef stbtt_uint8
|
||||
* typedef unsigned char stbtt_uint8;
|
||||
* typedef signed char stbtt_int8;
|
||||
* typedef unsigned short stbtt_uint16;
|
||||
* typedef signed short stbtt_int16;
|
||||
* typedef unsigned int stbtt_uint32;
|
||||
* typedef signed int stbtt_int32;
|
||||
* #endif
|
||||
*/
|
||||
|
||||
typedef char stbtt__check_size32[sizeof(stbtt_int32)==4 ? 1 : -1];
|
||||
typedef char stbtt__check_size16[sizeof(stbtt_int16)==2 ? 1 : -1];
|
||||
|
|
401
src/wellspring.c
401
src/wellspring.c
|
@ -29,120 +29,373 @@
|
|||
|
||||
#define STBTT_malloc(x,u) ((void)(u),Wellspring_malloc(x))
|
||||
#define STBTT_free(x,u) ((void)(u),Wellspring_free(x))
|
||||
#define STBTT_memcpy Wellspring_memcpy
|
||||
#define STBTT_memset Wellspring_memset
|
||||
#define STBTT_ifloor Wellspring_ifloor
|
||||
#define STBTT_iceil Wellspring_iceil
|
||||
#define STBTT_sqrt Wellspring_sqrt
|
||||
#define STBTT_pow Wellspring_pow
|
||||
#define STBTT_fmod Wellspring_fmod
|
||||
#define STBTT_cos Wellspring_cos
|
||||
#define STBTT_acos Wellspring_acos
|
||||
#define STBTT_fabs Wellspring_fabs
|
||||
#define STBTT_assert Wellspring_assert
|
||||
#define STBTT_strlen Wellspring_strlen
|
||||
|
||||
typedef uint8_t stbtt_uint8;
|
||||
typedef int8_t stbtt_int8;
|
||||
typedef uint16_t stbtt_uint16;
|
||||
typedef int16_t stbtt_int16;
|
||||
typedef uint32_t stbtt_uint32;
|
||||
typedef int32_t stbtt_int32;
|
||||
|
||||
#define STBTT_STATIC
|
||||
#define STB_TRUETYPE_IMPLEMENTATION
|
||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||
#include "stb_truetype.h"
|
||||
|
||||
typedef struct Font
|
||||
#define INITIAL_QUAD_CAPACITY 128
|
||||
|
||||
/* Structs */
|
||||
|
||||
typedef struct CharRange
|
||||
{
|
||||
uint8_t *fontData;
|
||||
stbtt_fontinfo stbFontInfo;
|
||||
} Font;
|
||||
stbtt_packedchar *data;
|
||||
int32_t firstCodepoint;
|
||||
uint32_t charCount;
|
||||
} CharRange;
|
||||
|
||||
typedef struct Packer
|
||||
{
|
||||
uint8_t *fontBytes;
|
||||
|
||||
stbtt_pack_context *context;
|
||||
uint8_t *pixels;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint32_t strideInBytes;
|
||||
uint32_t padding;
|
||||
|
||||
CharRange *ranges;
|
||||
uint32_t rangeCount;
|
||||
} Packer;
|
||||
|
||||
typedef struct Batch
|
||||
{
|
||||
Wellspring_Vertex *vertices;
|
||||
uint32_t vertexCount;
|
||||
uint32_t vertexCapacity;
|
||||
|
||||
uint32_t *indices;
|
||||
uint32_t indexCount;
|
||||
uint32_t indexCapacity;
|
||||
} Batch;
|
||||
|
||||
/* UTF-8 Decoder */
|
||||
|
||||
/* Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
|
||||
* See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details.
|
||||
*/
|
||||
|
||||
#define UTF8_ACCEPT 0
|
||||
#define UTF8_REJECT 1
|
||||
|
||||
static const uint8_t utf8d[] = {
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00..1f
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 20..3f
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 40..5f
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 60..7f
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, // 80..9f
|
||||
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, // a0..bf
|
||||
8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // c0..df
|
||||
0xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3, // e0..ef
|
||||
0xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8, // f0..ff
|
||||
0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1, // s0..s0
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1, // s1..s2
|
||||
1,2,1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1, // s3..s4
|
||||
1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1, // s5..s6
|
||||
1,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // s7..s8
|
||||
};
|
||||
|
||||
static uint32_t inline
|
||||
decode(uint32_t* state, uint32_t* codep, uint32_t byte) {
|
||||
uint32_t type = utf8d[byte];
|
||||
|
||||
*codep = (*state != UTF8_ACCEPT) ?
|
||||
(byte & 0x3fu) | (*codep << 6) :
|
||||
(0xff >> type) & (byte);
|
||||
|
||||
*state = utf8d[256 + *state*16 + type];
|
||||
return *state;
|
||||
}
|
||||
|
||||
/* API */
|
||||
|
||||
uint32_t Wellspring_LinkedVersion(void)
|
||||
{
|
||||
return WELLSPRING_COMPILED_VERSION;
|
||||
}
|
||||
|
||||
Wellspring_Font* Wellspring_CreateFont(
|
||||
const uint8_t *fontData,
|
||||
uint32_t fontDataLength
|
||||
) {
|
||||
Font *font;
|
||||
|
||||
font = Wellspring_malloc(sizeof(Font));
|
||||
Wellspring_memcpy(font->fontData, fontData, fontDataLength);
|
||||
stbtt_InitFont(&font->stbFontInfo, font->fontData, 0);
|
||||
|
||||
return (Wellspring_Font*) font;
|
||||
}
|
||||
|
||||
void Wellspring_GetFontMetrics(
|
||||
Wellspring_Font *font,
|
||||
int32_t *pAscent,
|
||||
int32_t *pDescent,
|
||||
int32_t *pLineGap
|
||||
) {
|
||||
Font *myFont = (Font*) font;
|
||||
stbtt_GetFontVMetrics(&myFont->stbFontInfo, pAscent, pDescent, pLineGap);
|
||||
}
|
||||
|
||||
int32_t Wellspring_FindGlyphIndex(
|
||||
Wellspring_Font *font,
|
||||
int32_t codepoint
|
||||
) {
|
||||
Font *myFont = (Font*) font;
|
||||
return stbtt_FindGlyphIndex(&myFont->stbFontInfo, codepoint);
|
||||
}
|
||||
|
||||
void Wellspring_GetGlyphMetrics(
|
||||
Wellspring_Font *font,
|
||||
int32_t glyphIndex,
|
||||
int32_t *pAdvance,
|
||||
int32_t *pLeftSideBearing
|
||||
) {
|
||||
Font *myFont = (Font*) font;
|
||||
stbtt_GetGlyphHMetrics(&myFont->stbFontInfo, glyphIndex, pAdvance, pLeftSideBearing);
|
||||
}
|
||||
|
||||
int32_t Wellspring_GetGlyphKernAdvance(
|
||||
Wellspring_Font *font,
|
||||
int32_t glyphIndexA,
|
||||
int32_t glyphIndexB
|
||||
) {
|
||||
Font *myFont = (Font*) font;
|
||||
stbtt_GetGlyphKernAdvance(&myFont->stbFontInfo, glyphIndexA, glyphIndexB);
|
||||
}
|
||||
|
||||
Wellspring_Packer* Wellspring_CreatePacker(
|
||||
uint8_t *pixels,
|
||||
uint8_t *fontBytes,
|
||||
uint32_t fontBytesLength,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
uint32_t strideInBytes,
|
||||
uint32_t padding
|
||||
) {
|
||||
Packer *packer = Wellspring_malloc(sizeof(Packer));
|
||||
|
||||
packer->fontBytes = Wellspring_malloc(fontBytesLength);
|
||||
Wellspring_memcpy(packer->fontBytes, fontBytes, fontBytesLength);
|
||||
|
||||
packer->context = Wellspring_malloc(sizeof(stbtt_pack_context));
|
||||
packer->pixels = Wellspring_malloc(sizeof(uint8_t) * width * height);
|
||||
|
||||
packer->width = width;
|
||||
packer->height = height;
|
||||
packer->strideInBytes = strideInBytes;
|
||||
packer->padding = padding;
|
||||
|
||||
packer->ranges = NULL;
|
||||
packer->rangeCount = 0;
|
||||
|
||||
stbtt_PackBegin(packer->context, packer->pixels, width, height, strideInBytes, padding, NULL);
|
||||
|
||||
return (Wellspring_Packer*) packer;
|
||||
}
|
||||
|
||||
uint32_t Wellspring_PackFontRanges(
|
||||
Wellspring_Packer *packer,
|
||||
Wellspring_Font *font,
|
||||
Wellspring_FontRange *ranges,
|
||||
uint32_t numRanges
|
||||
) {
|
||||
Packer *myPacker = (Packer*) packer;
|
||||
Wellspring_FontRange *currentFontRange;
|
||||
stbtt_pack_range stbPackRanges[numRanges];
|
||||
CharRange *currentCharRange;
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < numRanges; i += 1)
|
||||
{
|
||||
currentFontRange = &ranges[i];
|
||||
stbPackRanges[i].font_size = currentFontRange->fontSize;
|
||||
stbPackRanges[i].first_unicode_codepoint_in_range = currentFontRange->firstCodepoint;
|
||||
stbPackRanges[i].array_of_unicode_codepoints = NULL;
|
||||
stbPackRanges[i].num_chars = currentFontRange->numChars;
|
||||
stbPackRanges[i].h_oversample = currentFontRange->oversampleH;
|
||||
stbPackRanges[i].v_oversample = currentFontRange->oversampleV;
|
||||
stbPackRanges[i].chardata_for_range = Wellspring_malloc(sizeof(stbtt_packedchar) * currentFontRange->numChars);
|
||||
}
|
||||
|
||||
stbtt_PackFontRanges(myPacker->context, myPacker->fontBytes, 0, stbPackRanges, numRanges);
|
||||
|
||||
myPacker->rangeCount += numRanges;
|
||||
myPacker->ranges = Wellspring_realloc(myPacker->ranges, sizeof(CharRange) * myPacker->rangeCount);
|
||||
|
||||
for (i = 0; i < numRanges; i += 1)
|
||||
{
|
||||
currentCharRange = &myPacker->ranges[myPacker->rangeCount + i];
|
||||
currentCharRange->data = stbPackRanges[i].chardata_for_range;
|
||||
currentCharRange->firstCodepoint = stbPackRanges[i].first_unicode_codepoint_in_range;
|
||||
currentCharRange->charCount = stbPackRanges[i].num_chars;
|
||||
}
|
||||
|
||||
myPacker->rangeCount += numRanges;
|
||||
}
|
||||
|
||||
uint8_t* Wellspring_GetPixels(
|
||||
Wellspring_Packer *packer
|
||||
) {
|
||||
|
||||
}
|
||||
|
||||
uint32_t Wellspring_GetGlyphQuad(
|
||||
void Wellspring_GetPixels(
|
||||
Wellspring_Packer *packer,
|
||||
int32_t glyphIndex,
|
||||
Wellspring_GlyphQuad *pGlyphQuad
|
||||
uint8_t **pData
|
||||
) {
|
||||
Packer* myPacker = (Packer*) packer;
|
||||
*pData = myPacker->pixels;
|
||||
}
|
||||
|
||||
Wellspring_TextBatch* Wellspring_TextBatchCreate()
|
||||
{
|
||||
Batch *batch = Wellspring_malloc(sizeof(Batch));
|
||||
|
||||
batch->vertexCapacity = INITIAL_QUAD_CAPACITY * 4;
|
||||
batch->vertices = Wellspring_malloc(sizeof(Wellspring_Vertex) * batch->vertexCapacity);
|
||||
batch->vertexCount = 0;
|
||||
|
||||
batch->indexCapacity = INITIAL_QUAD_CAPACITY * 6;
|
||||
batch->indices = Wellspring_malloc(sizeof(uint32_t) * batch->indexCapacity);
|
||||
batch->indexCount = 0;
|
||||
|
||||
return (Wellspring_TextBatch*) batch;
|
||||
}
|
||||
|
||||
void Wellspring_TextBatchStart(Wellspring_TextBatch *textBatch)
|
||||
{
|
||||
Batch *batch = (Batch*) textBatch;
|
||||
batch->vertexCount = 0;
|
||||
batch->indexCount = 0;
|
||||
}
|
||||
|
||||
uint8_t Wellspring_DrawTextBatched(
|
||||
Wellspring_TextBatch *textBatch,
|
||||
Wellspring_Packer *packer,
|
||||
float x,
|
||||
float y,
|
||||
float depth,
|
||||
Wellspring_Color *color,
|
||||
const uint8_t *str,
|
||||
uint32_t strLength
|
||||
) {
|
||||
Batch *batch = (Batch*) textBatch;
|
||||
Packer *myPacker = (Packer*) packer;
|
||||
uint32_t decodeState = 0;
|
||||
uint32_t codepoint;
|
||||
int32_t glyphIndex;
|
||||
int32_t previousGlyphIndex;
|
||||
stbtt_packedchar *rangeData;
|
||||
stbtt_aligned_quad charQuad;
|
||||
uint32_t vertexBufferIndex;
|
||||
uint32_t indexBufferIndex;
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < strLength; i += 1)
|
||||
{
|
||||
if (decode(&decodeState, &codepoint, str[i]))
|
||||
{
|
||||
if (decodeState == UTF8_REJECT)
|
||||
{
|
||||
/* Something went very wrong */
|
||||
return 0;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Find the packed char data */
|
||||
for (i = 0; i < myPacker->rangeCount; i += 1)
|
||||
{
|
||||
if (
|
||||
codepoint >= myPacker->ranges[i].firstCodepoint &&
|
||||
codepoint < myPacker->ranges[i].firstCodepoint + myPacker->ranges[i].charCount
|
||||
) {
|
||||
rangeData = myPacker->ranges[i].data;
|
||||
glyphIndex = codepoint - myPacker->ranges[i].firstCodepoint;
|
||||
}
|
||||
}
|
||||
|
||||
stbtt_GetPackedQuad(
|
||||
rangeData,
|
||||
myPacker->width,
|
||||
myPacker->height,
|
||||
glyphIndex,
|
||||
&x,
|
||||
&y,
|
||||
&charQuad,
|
||||
1
|
||||
);
|
||||
|
||||
if (batch->vertexCount >= batch->vertexCapacity)
|
||||
{
|
||||
batch->vertexCapacity *= 2;
|
||||
batch->vertices = Wellspring_realloc(batch->vertices, sizeof(Wellspring_Vertex) * batch->vertexCapacity);
|
||||
}
|
||||
|
||||
if (batch->indexCount >= batch->indexCapacity)
|
||||
{
|
||||
batch->indexCapacity *= 2;
|
||||
batch->indices = Wellspring_realloc(batch->indices, sizeof(uint32_t) * batch->indexCapacity);
|
||||
}
|
||||
|
||||
/* TODO: kerning and alignment */
|
||||
|
||||
vertexBufferIndex = batch->vertexCount;
|
||||
indexBufferIndex = batch->indexCount;
|
||||
|
||||
batch->vertices[vertexBufferIndex].x = charQuad.x0;
|
||||
batch->vertices[vertexBufferIndex].y = charQuad.y0;
|
||||
batch->vertices[vertexBufferIndex].z = depth;
|
||||
batch->vertices[vertexBufferIndex].u = charQuad.s0;
|
||||
batch->vertices[vertexBufferIndex].v = charQuad.t0;
|
||||
batch->vertices[vertexBufferIndex].r = color->r;
|
||||
batch->vertices[vertexBufferIndex].g = color->g;
|
||||
batch->vertices[vertexBufferIndex].b = color->b;
|
||||
batch->vertices[vertexBufferIndex].a = color->a;
|
||||
|
||||
batch->vertices[vertexBufferIndex + 1].x = charQuad.x0;
|
||||
batch->vertices[vertexBufferIndex + 1].y = charQuad.y1;
|
||||
batch->vertices[vertexBufferIndex + 1].z = depth;
|
||||
batch->vertices[vertexBufferIndex + 1].u = charQuad.s0;
|
||||
batch->vertices[vertexBufferIndex + 1].v = charQuad.t1;
|
||||
batch->vertices[vertexBufferIndex + 1].r = color->r;
|
||||
batch->vertices[vertexBufferIndex + 1].g = color->g;
|
||||
batch->vertices[vertexBufferIndex + 1].b = color->b;
|
||||
batch->vertices[vertexBufferIndex + 1].a = color->a;
|
||||
|
||||
batch->vertices[vertexBufferIndex + 2].x = charQuad.x1;
|
||||
batch->vertices[vertexBufferIndex + 2].y = charQuad.y0;
|
||||
batch->vertices[vertexBufferIndex + 2].z = depth;
|
||||
batch->vertices[vertexBufferIndex + 2].u = charQuad.s1;
|
||||
batch->vertices[vertexBufferIndex + 2].v = charQuad.t0;
|
||||
batch->vertices[vertexBufferIndex + 2].r = color->r;
|
||||
batch->vertices[vertexBufferIndex + 2].g = color->g;
|
||||
batch->vertices[vertexBufferIndex + 2].b = color->b;
|
||||
batch->vertices[vertexBufferIndex + 2].a = color->a;
|
||||
|
||||
batch->vertices[vertexBufferIndex + 3].x = charQuad.x1;
|
||||
batch->vertices[vertexBufferIndex + 3].y = charQuad.y1;
|
||||
batch->vertices[vertexBufferIndex + 3].z = depth;
|
||||
batch->vertices[vertexBufferIndex + 3].u = charQuad.s1;
|
||||
batch->vertices[vertexBufferIndex + 3].v = charQuad.t1;
|
||||
batch->vertices[vertexBufferIndex + 3].r = color->r;
|
||||
batch->vertices[vertexBufferIndex + 3].g = color->g;
|
||||
batch->vertices[vertexBufferIndex + 3].b = color->b;
|
||||
batch->vertices[vertexBufferIndex + 3].a = color->a;
|
||||
|
||||
batch->indices[indexBufferIndex] = vertexBufferIndex;
|
||||
batch->indices[indexBufferIndex + 1] = vertexBufferIndex + 1;
|
||||
batch->indices[indexBufferIndex + 2] = vertexBufferIndex + 2;
|
||||
batch->indices[indexBufferIndex + 3] = vertexBufferIndex + 2;
|
||||
batch->indices[indexBufferIndex + 4] = vertexBufferIndex + 1;
|
||||
batch->indices[indexBufferIndex + 5] = vertexBufferIndex + 3;
|
||||
|
||||
batch->vertexCount += 4;
|
||||
batch->indexCount += 6;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Wellspring_TextBatchGetBufferLengths(
|
||||
Wellspring_TextBatch *textBatch,
|
||||
uint32_t *pVertexLength,
|
||||
uint32_t *pIndexLength
|
||||
) {
|
||||
Batch *batch = (Batch*) textBatch;
|
||||
*pVertexLength = batch->vertexCount;
|
||||
*pIndexLength = batch->indexCount;
|
||||
}
|
||||
|
||||
void Wellspring_TextBatchGetBuffers(
|
||||
Wellspring_TextBatch *textBatch,
|
||||
Wellspring_Vertex **pVertexBuffer,
|
||||
uint32_t **pIndexBuffer
|
||||
) {
|
||||
Batch *batch = (Batch*) textBatch;
|
||||
*pVertexBuffer = batch->vertices;
|
||||
*pIndexBuffer = batch->indices;
|
||||
}
|
||||
|
||||
void Wellspring_TextBatchDestroy(Wellspring_TextBatch *textBatch)
|
||||
{
|
||||
Batch *batch = (Batch*) textBatch;
|
||||
Wellspring_free(batch->vertices);
|
||||
Wellspring_free(batch->indices);
|
||||
Wellspring_free(batch);
|
||||
}
|
||||
|
||||
void Wellspring_DestroyPacker(Wellspring_Packer *packer)
|
||||
{
|
||||
Packer* myPacker = (Packer*) packer;
|
||||
|
||||
}
|
||||
|
||||
void Wellspring_DestroyFont(
|
||||
Wellspring_Font *font
|
||||
) {
|
||||
Font* myFont = (Font*) font;
|
||||
|
||||
Wellspring_free(myFont->fontData);
|
||||
Wellspring_free(myFont);
|
||||
Wellspring_free(myPacker->fontBytes);
|
||||
Wellspring_free(myPacker->context);
|
||||
Wellspring_free(myPacker->pixels);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue