mirror of
https://github.com/Relintai/sfw.git
synced 2024-12-20 21:06:49 +01:00
Initial font meshing setup. Also various cleanups.
This commit is contained in:
parent
5a572e2dc5
commit
80172bfee4
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user