lovr.graphics.print geometry;

This commit is contained in:
bjorn 2017-02-16 16:23:52 -08:00
parent 1b2527db18
commit ebb40867e0
5 changed files with 45 additions and 45 deletions

View File

@ -1,7 +1,6 @@
#include "graphics/font.h" #include "graphics/font.h"
#include "graphics/graphics.h" #include "graphics/graphics.h"
#include "graphics/texture.h" #include "graphics/texture.h"
#include "math/mat4.h"
#include "loaders/font.h" #include "loaders/font.h"
#include "loaders/texture.h" #include "loaders/texture.h"
#include "util.h" #include "util.h"
@ -53,11 +52,11 @@ void lovrFontDestroy(const Ref* ref) {
free(font); free(font);
} }
void lovrFontPrint(Font* font, const char* str, mat4 transform) { void lovrFontPrint(Font* font, const char* str, float x, float y, float z, float w, float h, float angle, float ax, float ay, float az) {
FontAtlas* atlas = &font->atlas; FontAtlas* atlas = &font->atlas;
float x = 0; float cx = 0;
float y = -lovrFontGetHeight(font); float cy = -lovrFontGetHeight(font);
float u = atlas->width; float u = atlas->width;
float v = atlas->height; float v = atlas->height;
@ -68,7 +67,7 @@ void lovrFontPrint(Font* font, const char* str, mat4 transform) {
unsigned int codepoint; unsigned int codepoint;
size_t bytes; size_t bytes;
int lineX = 0; int linePtr = 0;
vec_reserve(&font->vertices, len * 30); vec_reserve(&font->vertices, len * 30);
vec_clear(&font->vertices); vec_clear(&font->vertices);
@ -79,20 +78,20 @@ void lovrFontPrint(Font* font, const char* str, mat4 transform) {
if (codepoint == '\n') { if (codepoint == '\n') {
// Center the line // Center the line
while (lineX < font->vertices.length) { while (linePtr < font->vertices.length) {
font->vertices.data[lineX] -= x / 2; font->vertices.data[linePtr] -= cx / 2;
lineX += 5; linePtr += 5;
} }
x = 0; cx = 0;
y -= font->fontData->size * font->lineHeight; cy -= font->fontData->size * font->lineHeight;
previous = '\0'; previous = '\0';
str += bytes; str += bytes;
continue; continue;
} }
// Kerning // Kerning
x += lovrFontGetKerning(font, previous, codepoint); cx += lovrFontGetKerning(font, previous, codepoint);
previous = codepoint; previous = codepoint;
// Get glyph // Get glyph
@ -100,30 +99,22 @@ void lovrFontPrint(Font* font, const char* str, mat4 transform) {
// Start over if texture was repacked // Start over if texture was repacked
if (u != atlas->width || v != atlas->height) { if (u != atlas->width || v != atlas->height) {
lovrFontPrint(font, start, transform); lovrFontPrint(font, start, x, y, z, w, h, angle, ax, ay, az);
return; return;
} }
// Glyph geometry
int gx = glyph->x;
int gy = glyph->y;
int gw = glyph->w;
int gh = glyph->h;
int dx = glyph->dx;
int dy = glyph->dy;
// Triangles // Triangles
if (gw > 0 && gh > 0) { if (glyph->w > 0 && glyph->h > 0) {
float x1 = x + dx; float x1 = cx + glyph->dx;
float y1 = y + dy; float y1 = cy + glyph->dy;
float x2 = x1 + gw; float x2 = x1 + glyph->w;
float y2 = y1 - gh; float y2 = y1 - glyph->h;
float s1 = gx / u; float s1 = glyph->x / u;
float t1 = gy / v; float t1 = glyph->y / v;
float s2 = (gx + gw) / u; float s2 = (glyph->x + glyph->w) / u;
float t2 = (gy + gh) / v; float t2 = (glyph->y + glyph->h) / v;
float v[30] = { float vertices[30] = {
x1, y1, 0, s1, t1, x1, y1, 0, s1, t1,
x1, y2, 0, s1, t2, x1, y2, 0, s1, t2,
x2, y1, 0, s2, t1, x2, y1, 0, s2, t1,
@ -132,26 +123,29 @@ void lovrFontPrint(Font* font, const char* str, mat4 transform) {
x2, y2, 0, s2, t2 x2, y2, 0, s2, t2
}; };
vec_pusharr(&font->vertices, v, 30); vec_pusharr(&font->vertices, vertices, 30);
} }
// Advance cursor // Advance cursor
x += glyph->advance; cx += glyph->advance;
str += bytes; str += bytes;
} }
// Center the last line // Center the last line
while (lineX < font->vertices.length) { while (linePtr < font->vertices.length) {
font->vertices.data[lineX] -= x / 2; font->vertices.data[linePtr] -= cx / 2;
lineX += 5; linePtr += 5;
} }
// We override the depth test to LEQUAL to prevent blending issues with glyphs, not great // We override the depth test to LEQUAL to prevent blending issues with glyphs, not great
CompareMode oldCompareMode = lovrGraphicsGetDepthTest(); CompareMode oldCompareMode = lovrGraphicsGetDepthTest();
float scale = h / font->fontData->height;
lovrGraphicsPush(); lovrGraphicsPush();
lovrGraphicsMatrixTransform(transform); lovrGraphicsTranslate(x, y, z);
lovrGraphicsTranslate(0, -y / 2, 0); lovrGraphicsScale(scale, scale, scale);
lovrGraphicsRotate(angle, ax, ay, az);
lovrGraphicsTranslate(0, -cy / 2, 0);
lovrGraphicsSetDepthTest(COMPARE_LEQUAL); lovrGraphicsSetDepthTest(COMPARE_LEQUAL);
lovrGraphicsSetShapeData(font->vertices.data, font->vertices.length); lovrGraphicsSetShapeData(font->vertices.data, font->vertices.length);
lovrGraphicsDrawPrimitive(GL_TRIANGLES, font->texture, 0, 1, 0); lovrGraphicsDrawPrimitive(GL_TRIANGLES, font->texture, 0, 1, 0);

View File

@ -1,6 +1,5 @@
#include "util.h" #include "util.h"
#include "graphics/texture.h" #include "graphics/texture.h"
#include "math/math.h"
#include "vendor/map/map.h" #include "vendor/map/map.h"
#include "vendor/vec/vec.h" #include "vendor/vec/vec.h"
#include <stdint.h> #include <stdint.h>
@ -50,7 +49,7 @@ typedef struct {
Font* lovrFontCreate(FontData* fontData); Font* lovrFontCreate(FontData* fontData);
void lovrFontDestroy(const Ref* ref); void lovrFontDestroy(const Ref* ref);
void lovrFontPrint(Font* font, const char* str, mat4 transform); void lovrFontPrint(Font* font, const char* str, float x, float y, float z, float w, float h, float angle, float ax, float ay, float az);
int lovrFontGetWidth(Font* font, const char* str); int lovrFontGetWidth(Font* font, const char* str);
int lovrFontGetHeight(Font* font); int lovrFontGetHeight(Font* font);
int lovrFontGetAscent(Font* font); int lovrFontGetAscent(Font* font);

View File

@ -682,7 +682,7 @@ void lovrGraphicsSkybox(Skybox* skybox, float angle, float ax, float ay, float a
lovrGraphicsPop(); lovrGraphicsPop();
} }
void lovrGraphicsPrint(const char* str, mat4 transform) { void lovrGraphicsPrint(const char* str, float x, float y, float z, float w, float h, float angle, float ax, float ay, float az) {
lovrGraphicsEnsureFont(); lovrGraphicsEnsureFont();
lovrFontPrint(state.activeFont, str, transform); lovrFontPrint(state.activeFont, str, x, y, z, w, h, angle, ax, ay, az);
} }

View File

@ -141,4 +141,4 @@ void lovrGraphicsPlane(DrawMode mode, Texture* texture, float x, float y, float
void lovrGraphicsPlaneFullscreen(Texture* texture); void lovrGraphicsPlaneFullscreen(Texture* texture);
void lovrGraphicsCube(DrawMode mode, Texture* texture, mat4 transform); void lovrGraphicsCube(DrawMode mode, Texture* texture, mat4 transform);
void lovrGraphicsSkybox(Skybox* skybox, float angle, float ax, float ay, float az); void lovrGraphicsSkybox(Skybox* skybox, float angle, float ax, float ay, float az);
void lovrGraphicsPrint(const char* str, mat4 transform); void lovrGraphicsPrint(const char* str, float x, float y, float z, float w, float h, float angle, float ax, float ay, float az);

View File

@ -551,9 +551,16 @@ int l_lovrGraphicsCube(lua_State* L) {
int l_lovrGraphicsPrint(lua_State* L) { int l_lovrGraphicsPrint(lua_State* L) {
const char* str = luaL_checkstring(L, 1); const char* str = luaL_checkstring(L, 1);
float transform[16]; float x = luaL_optnumber(L, 2, 0);
luax_readtransform(L, 2, transform); float y = luaL_optnumber(L, 3, 0);
lovrGraphicsPrint(str, transform); float z = luaL_optnumber(L, 4, 0);
float w = luaL_optnumber(L, 5, 0);
float h = luaL_optnumber(L, 6, 1);
float angle = luaL_optnumber(L, 7, 0);
float ax = luaL_optnumber(L, 8, 0);
float ay = luaL_optnumber(L, 9, 1);
float az = luaL_optnumber(L, 10, 0);
lovrGraphicsPrint(str, x, y, z, w, h, angle, ax, ay, az);
return 0; return 0;
} }