Initial font meshing setup. Also various cleanups.

This commit is contained in:
Relintai 2024-01-04 14:37:11 +01:00
parent 5a572e2dc5
commit 80172bfee4
6 changed files with 330 additions and 198 deletions

View File

@ -98,6 +98,8 @@ void GameScene::render() {
_font_test_sprite->render();
_font_test_mi->render();
//TextRenderer::get_singleton()->font_init();
//TextRenderer::get_singleton()->font_print("test");
}
@ -120,7 +122,7 @@ GameScene::GameScene() {
_font_test_sprite = memnew(Sprite);
_font_test_mat = new TextureMaterial2D();
_font_test_mat = memnew(TextureMaterial2D());
_font_test_mat->texture = _font->get_texture().ptr();
_font_test_sprite->mesh_instance->material = _font_test_mat;
_font_test_sprite->width = _font->get_atlas_width();
@ -128,6 +130,17 @@ GameScene::GameScene() {
_font_test_sprite->transform.set_origin(Vector2(1000, 100));
_font_test_sprite->update_mesh();
_font_test_mesh.instance();
_font_test_mi = memnew(MeshInstance2D());
_font_test_mi->material = _font_test_mat;
_font_test_mi->mesh = _font_test_mesh.ptr();
//_font_test_mi->transform.scale(Vector2(32, 32));
_font_test_mi->transform.set_origin(Vector2(1000, 500));
_font->generate_mesh("asdfghjklqwetyuiop\nzxcvbnm", _font_test_mesh);
_font_test_mesh->upload();
image.instance();
image->load_from_file("icon.png");
//image->bumpmap_to_normalmap();

View File

@ -13,6 +13,7 @@
#include "render_core/texture_material_2d.h"
#include "render_objects/camera_2d.h"
#include "render_objects/camera_3d.h"
#include "render_objects/mesh_instance_2d.h"
#include "render_objects/mesh_instance_3d.h"
#include "render_objects/sprite.h"
#include "render_objects/tile_map.h"
@ -41,6 +42,9 @@ public:
Sprite *_font_test_sprite;
TextureMaterial2D *_font_test_mat;
Ref<Mesh> _font_test_mesh;
MeshInstance2D *_font_test_mi;
Camera2D *camera_2d;
TileMap *tile_map;
Sprite *sprite;

View File

@ -43,6 +43,7 @@
#include "font_data_tables.inc.h"
#include "render_core/image.h"
#include "render_core/mesh.h"
#include "render_core/texture.h"
void Font::load_default(const float size, const uint32_t flags) {
@ -287,23 +288,33 @@ void Font::font_face_from_mem(const void *ttf_data, uint32_t ttf_len, float font
}
stbtt_packedchar *cd = &_cdata[cp - _begin];
// if(cd->x1==cd->x0) { _iter2cp[i] = _cp2iter[cp - _begin] = 0xFFFD; continue; }
TextureOffset offset;
offset.x = cd->x0 / (double)_width;
offset.y = cd->y0 / (double)_height;
offset.w = (cd->x1 - cd->x0) / (double)_width;
offset.h = (cd->y1 - cd->y0) / (double)_height;
offset.x0 = cd->x0 / (double)_width;
offset.y0 = cd->y0 / (double)_height;
//offset.x1 = (cd->x1 - cd->x0) / (double)_width;
//offset.y1 = (cd->y1 - cd->y0) / (double)_height;
offset.x1 = cd->x1 / (double)_width;
offset.y1 = cd->y1 / (double)_height;
offset.xoff = cd->xoff / (double)_width;
offset.yoff = cd->yoff / (double)_height;
offset.woff = cd->xoff2 / (double)_width;
offset.hoff = cd->yoff2 / (double)_height;
//offset.xoff = cd->xoff / (double)_width;
//offset.yoff = cd->yoff / (double)_height;
//offset.xoff2 = cd->xoff / (double)_width;
//offset.yoff2 = cd->yoff / (double)_height;
//offset.xadvance = cd->xadvance / (double)_width;
offset.xoff = cd->xoff;
offset.yoff = cd->yoff;
offset.xoff2 = cd->xoff;
offset.yoff2 = cd->yoff;
offset.xadvance = cd->xadvance;
_texture_offsets.write[i] = offset;
}
_initialized = true;
/*
float *texture_offsets = memnew_arr(float, 8 * _num_glyphs);
@ -355,6 +366,74 @@ void Font::font_face(const char *filename_ttf, float font_size, unsigned flags)
*/
}
Vector2 Font::generate_mesh(const String &p_text, Ref<Mesh> &p_into, const Color &p_color) {
ERR_FAIL_COND_V(!_initialized, Vector2());
ERR_FAIL_COND_V(!p_into.is_valid(), Vector2());
float X = 0;
float Y = 0;
float W = 0;
float L = _ascent * _factor * _scale;
float LL = L; // LL=largest linedist
float current_x_pos = 0;
// parse string
for (int i = 0, end = p_text.length(); i < end; ++i) {
uint32_t ch = p_text[i];
if (ch == '\n') {
// change cursor, advance y, record largest x as width, increase height
if (X > W) {
W = X;
}
X = 0.0;
Y += _linedist * _factor * _scale;
if (i + 1 == end) { //@hack: ensures we terminate the height at the correct position
Y += (_descent + _linegap) * _factor * _scale;
}
continue;
}
int cp = ch - _begin;
//*t++ = X;
//*t++ = Y;
//*t++ = _cp2iter[cp];
//*t++ = col ? col[i] : color;
const TextureOffset &t = _texture_offsets[_cp2iter[cp]];
p_into->add_uv(t.x0, t.y0);
p_into->add_color(p_color);
p_into->add_vertex2(current_x_pos, Y);
p_into->add_uv(t.x1, t.y1);
p_into->add_color(p_color);
p_into->add_vertex2(current_x_pos + 20, Y + 20);
p_into->add_uv(t.x0, t.y1);
p_into->add_color(p_color);
p_into->add_vertex2(current_x_pos, Y + 20);
p_into->add_uv(t.x1, t.y0);
p_into->add_color(p_color);
p_into->add_vertex2(current_x_pos + 20, Y + 20);
p_into->add_triangle(1, 0, 2);
p_into->add_triangle(0, 1, 3);
current_x_pos += 20;
X += _cdata[cp].xadvance * _scale;
}
return Vector2(W * W > X * X ? W : X, Y * Y > LL * LL ? Y : LL).abs();
}
void Font::font_draw_cmd(const float *glyph_data, int glyph_idx, float factor, Vector2 offset) {
/*
// Backup GL state
@ -533,43 +612,65 @@ Vector2 Font::font_draw_ex(const String &text, Vector2 offset, const char *col,
return Vector2();
}
// Return cursor
Vector2 Font::font_xy() {
return gotoxy;
}
// Relocate cursor
void Font::font_goto(float x, float y) {
gotoxy = Vector2(x, y);
}
// Calculate the size of a string, in the pixel size specified. Count stray newlines too.
Vector2 Font::font_rect(const String &str) {
return font_draw_ex(str, gotoxy, NULL, NULL);
}
Vector2 Font::get_string_size(const String &text) {
ERR_FAIL_COND_V(!_initialized, Vector2());
Font::font_metrics_t Font::font_metrics(const String &text) {
font_metrics_t m = { 0 };
// sanity checks
int len = text.length();
/*
// ready
float X = 0;
float Y = 0;
float W = 0;
float L = _ascent * _factor * _scale;
float LL = L; // LL=largest linedist
// parse string
for (int i = 0, end = text.length(); i < end; ++i) {
for (int i = 0; i < len; ++i) {
uint32_t ch = text[i];
if (ch >= 1 && ch <= 6) {
S = ch;
continue;
}
if (ch >= 0x1a && ch <= 0x1f) {
if (fonts[ch - 0x1a].initialized) {
// change face
f = &fonts[ch - 0x1a];
}
continue;
}
if (ch == '\n') {
// change cursor, advance y, record largest x as width, increase height
if (X > W) {
W = X;
}
*/
X = 0.0;
Y -= _linedist * _factor * _scale;
if (i + 1 == len) { //@hack: ensures we terminate the height at the correct position
Y -= (_descent + _linegap) * _factor * _scale;
}
continue;
}
if (ch >= 1 && ch <= 6) {
L = _ascent * _factor * _scale;
if (L > LL) {
LL = L;
}
continue;
}
int cp = ch - _begin;
//*t++ = X;
//*t++ = Y;
//*t++ = _cp2iter[cp];
//*t++ = col ? col[i] : color;
X += _cdata[cp].xadvance * _scale;
}
return Vector2(W * W > X * X ? W : X, Y * Y > LL * LL ? Y : LL).abs();
}
Font::FontMetrics Font::font_metrics() {
FontMetrics m;
m.ascent = _ascent * _factor * _scale;
m.descent = _descent * _factor * _scale;

View File

@ -5,6 +5,9 @@
// font framework originally from FWK
// - rlyeh, public domain
#include "core/color.h"
#include "core/ustring.h"
#include "object/resource.h"
#include "core/ustring.h"
@ -15,6 +18,7 @@
class Image;
class Texture;
class Mesh;
class Font : public Resource {
SFW_OBJECT(Font, Resource);
@ -51,12 +55,12 @@ public:
// FONT_DEFAULTS = FONT_512 | FONT_NO_OVERSAMPLE | FONT_ASCII,
};
typedef struct font_metrics_t {
struct FontMetrics {
float ascent; // max distance above baseline for all glyphs
float descent; // max distance below baseline for all glyphs
float linegap; // distance betwen ascent of next line and descent of current line
float linedist; // distance between the baseline of two lines (ascent - descent + linegap)
} font_metrics_t;
};
void load_default(const float size, const uint32_t flags = 0);
@ -68,11 +72,10 @@ public:
void font_face_from_mem(const void *ttf_buffer, uint32_t ttf_len, float font_size, uint32_t flags);
// commands
Vector2 font_xy();
void font_goto(float x, float y);
Vector2 generate_mesh(const String &p_text, Ref<Mesh> &p_into, const Color &p_color = Color(1, 1, 1, 1));
Vector2 font_print(const String &text);
Vector2 font_rect(const String &str);
font_metrics_t font_metrics(const String &text);
Vector2 get_string_size(const String &text);
FontMetrics font_metrics();
int get_atlas_width();
int get_atlas_height();
@ -111,23 +114,22 @@ protected:
Ref<Texture> _texture;
struct TextureOffset {
float x;
float y;
float w;
float h;
float x0;
float y0;
float x1;
float y1;
float xoff;
float xoff2;
float xadvance;
float yoff;
float woff;
float hoff;
float yoff2;
};
Vector<TextureOffset> _texture_offsets;
static void font_draw_cmd(const float *glyph_data, int glyph_idx, float factor, Vector2 offset);
Vector2 font_draw_ex(const String &text, Vector2 offset, const char *col, void (*draw_cmd)(const float *, int, float, Vector2));
Vector2 gotoxy;
};
#endif

View File

@ -23,6 +23,12 @@ void Mesh::add_color(float r, float g, float b, float a) {
colors.push_back(b);
colors.push_back(a);
}
void Mesh::add_color(const Color &p_color) {
colors.push_back(p_color.r);
colors.push_back(p_color.g);
colors.push_back(p_color.b);
colors.push_back(p_color.a);
}
void Mesh::add_uv(float u, float v) {
uvs.push_back(u);

View File

@ -3,16 +3,22 @@
#include "core/vector.h"
#include <inttypes.h>
#include "core/color.h"
#include "object/resource.h"
#include "render_core/3rd_glad.h"
class Mesh {
class Mesh : public Resource {
SFW_OBJECT(Mesh, Resource);
public:
void add_vertex2(float x, float y);
void add_vertex3(float x, float y, float z);
void add_normal(float x, float y, float z);
void add_color(float r = 1, float g = 1, float b = 1, float a = 1);
void add_color(const Color &p_color);
void add_uv(float u, float v);