[update] Improved text drawing.
Now it uses degenerated polygons.
This commit is contained in:
parent
93f6844a2b
commit
d5039cc431
@ -153,6 +153,7 @@ private class FirstSetupState : AbstractSceneState {
|
|||||||
|
|
||||||
cube_interval_ease_ = Easing!float(cube_interval, LoadingCubeInterval);
|
cube_interval_ease_ = Easing!float(cube_interval, LoadingCubeInterval);
|
||||||
}
|
}
|
||||||
|
owner.text_.Clear();
|
||||||
}
|
}
|
||||||
override UpdateResult Update(KeyInput input) {
|
override UpdateResult Update(KeyInput input) {
|
||||||
const ratio = anime_.Update();
|
const ratio = anime_.Update();
|
||||||
@ -208,13 +209,12 @@ private class SongAppearState : AbstractSceneState {
|
|||||||
sfSound_setBuffer(owner.sound_, owner.soundres_.spotlight);
|
sfSound_setBuffer(owner.sound_, owner.soundres_.spotlight);
|
||||||
sfSound_play(owner.sound_);
|
sfSound_play(owner.sound_);
|
||||||
|
|
||||||
// TODO:
|
|
||||||
const song = owner.songs_[song_index_];
|
const song = owner.songs_[song_index_];
|
||||||
with (owner.text_) {
|
with (owner.text_) {
|
||||||
matrix.scale = vec3(0.2, 0.05, 0.05);
|
const w = LoadGlyphs(vec2i(256, 64),
|
||||||
matrix.translation = vec3(0, -0.3, 0);
|
song.name.to!dstring, vec2i(40, 0), owner.fonts_.gothic);
|
||||||
LoadGlyphs(vec2i(256, 64),
|
matrix.scale = vec3(-0.002, 0.002, 0.002);
|
||||||
song.name.to!dstring, vec2i(32, 0), owner.fonts_.gothic);
|
matrix.translation = vec3(-w/2*matrix.scale.x, -0.4, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
override UpdateResult Update(KeyInput input) {
|
override UpdateResult Update(KeyInput input) {
|
||||||
|
129
src/sj/Text.d
129
src/sj/Text.d
@ -1,7 +1,8 @@
|
|||||||
/// License: MIT
|
/// License: MIT
|
||||||
module sj.Text;
|
module sj.Text;
|
||||||
|
|
||||||
import std.exception;
|
import std.conv,
|
||||||
|
std.exception;
|
||||||
|
|
||||||
import gl4d, ft4d;
|
import gl4d, ft4d;
|
||||||
|
|
||||||
@ -17,52 +18,89 @@ class Text {
|
|||||||
texture_ = Texture2D.Create();
|
texture_ = Texture2D.Create();
|
||||||
vao_ = VertexArray.Create();
|
vao_ = VertexArray.Create();
|
||||||
vertices_ = ArrayBuffer.Create();
|
vertices_ = ArrayBuffer.Create();
|
||||||
|
indices_ = ElementArrayBuffer.Create();
|
||||||
|
|
||||||
program_.SetupVertexArray(vao_, vertices_);
|
program_.SetupVertexArray(vao_, vertices_);
|
||||||
|
|
||||||
vertices_.Bind();
|
|
||||||
ArrayBufferAllocator allocator;
|
|
||||||
with (allocator) {
|
|
||||||
const v = [
|
|
||||||
-1f, 1f, 0f, 1f, 0f,
|
|
||||||
-1f, -1f, 0f, 1f, 1f,
|
|
||||||
1f, -1f, 0f, 0f, 1f,
|
|
||||||
1f, 1f, 0f, 0f, 0f,
|
|
||||||
];
|
|
||||||
data = v.ptr;
|
|
||||||
size = v.length * v[0].sizeof;
|
|
||||||
usage = GL_STATIC_DRAW;
|
|
||||||
Allocate(vertices_);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
void LoadGlyphs(vec2i texsz, dstring text, vec2i charsz, FaceRef face)
|
float LoadGlyphs(vec2i texsz, dstring text, vec2i charsz, FaceRef face)
|
||||||
in (texsz.x > 0 && texsz.y > 0) {
|
in (texsz.x > 0 && texsz.y > 0) {
|
||||||
auto pixels = new ubyte[texsz.x * texsz.y];
|
static assert(TextProgram.Vertex.sizeof == float.sizeof * 5);
|
||||||
|
|
||||||
|
vertices_.Bind();
|
||||||
|
ArrayBufferAllocator vertices_allocator;
|
||||||
|
with (ArrayBufferAllocator()) {
|
||||||
|
size = text.length * TextProgram.Vertex.sizeof * 4;
|
||||||
|
usage = GL_STATIC_DRAW;
|
||||||
|
Allocate(vertices_);
|
||||||
|
}
|
||||||
|
auto vertices_data = vertices_.MapToWrite!float;
|
||||||
|
auto vertices_ptr = vertices_data.entity;
|
||||||
|
auto pixels = new ubyte[texsz.x * texsz.y];
|
||||||
|
|
||||||
GlyphLoader gloader;
|
GlyphLoader gloader;
|
||||||
gloader.pxWidth = charsz.x;
|
gloader.pxWidth = charsz.x;
|
||||||
gloader.pxHeight = charsz.y;
|
gloader.pxHeight = charsz.y;
|
||||||
gloader.flags = FT_LOAD_DEFAULT | FT_LOAD_RENDER;
|
gloader.flags = FT_LOAD_DEFAULT | FT_LOAD_RENDER;
|
||||||
|
|
||||||
int x;
|
int bmp_width;
|
||||||
|
float text_width = 0;
|
||||||
foreach (c; text) {
|
foreach (c; text) {
|
||||||
with (gloader) {
|
with (gloader) {
|
||||||
character = c;
|
character = c;
|
||||||
Load(face).enforce;
|
Load(face).enforce;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bitmap = face.EnforceGlyphBitmap();
|
const bitmap = face.EnforceGlyphBitmap();
|
||||||
const srcsz = vec2i(bitmap.width, bitmap.rows);
|
const srcsz = vec2i(bitmap.width, bitmap.rows);
|
||||||
CopyRawPixels(bitmap.buffer, srcsz, pixels.ptr, texsz, vec2i(x, 0));
|
CopyRawPixels(bitmap.buffer, srcsz, pixels.ptr, texsz, vec2i(bmp_width, 0));
|
||||||
|
|
||||||
x += srcsz.x;
|
const m = &face.glyph.metrics;
|
||||||
|
const bearing_x = m.horiBearingX*1f / m.width * srcsz.x;
|
||||||
|
const bearing_y = m.horiBearingY*1f / m.height * srcsz.y;
|
||||||
|
const advance = m.horiAdvance *1f / m.width * srcsz.x;
|
||||||
|
|
||||||
|
const posleft = text_width + bearing_x;
|
||||||
|
const posright = posleft + srcsz.x;
|
||||||
|
const postop = bearing_y;
|
||||||
|
const posbottom = postop - srcsz.y;
|
||||||
|
|
||||||
|
const uvleft = bmp_width*1f / texsz.x;
|
||||||
|
const uvright = (bmp_width + srcsz.x)*1f / texsz.x;
|
||||||
|
const uvtop = 0f;
|
||||||
|
const uvbottom = srcsz.y*1f / texsz.y;
|
||||||
|
|
||||||
|
*vertices_ptr++ = posleft;
|
||||||
|
*vertices_ptr++ = postop;
|
||||||
|
*vertices_ptr++ = 0;
|
||||||
|
*vertices_ptr++ = uvleft;
|
||||||
|
*vertices_ptr++ = uvtop;
|
||||||
|
|
||||||
|
*vertices_ptr++ = posleft;
|
||||||
|
*vertices_ptr++ = posbottom;
|
||||||
|
*vertices_ptr++ = 0;
|
||||||
|
*vertices_ptr++ = uvleft;
|
||||||
|
*vertices_ptr++ = uvbottom;
|
||||||
|
|
||||||
|
*vertices_ptr++ = posright;
|
||||||
|
*vertices_ptr++ = postop;
|
||||||
|
*vertices_ptr++ = 0;
|
||||||
|
*vertices_ptr++ = uvright;
|
||||||
|
*vertices_ptr++ = uvtop;
|
||||||
|
|
||||||
|
*vertices_ptr++ = posright;
|
||||||
|
*vertices_ptr++ = posbottom;
|
||||||
|
*vertices_ptr++ = 0;
|
||||||
|
*vertices_ptr++ = uvright;
|
||||||
|
*vertices_ptr++ = uvbottom;
|
||||||
|
|
||||||
|
bmp_width += srcsz.x;
|
||||||
|
text_width += advance;
|
||||||
}
|
}
|
||||||
|
|
||||||
texture_.Bind();
|
texture_.Bind();
|
||||||
Texture2DAllocator allocator;
|
Texture2DAllocator texture_allocator;
|
||||||
with (allocator) {
|
with (texture_allocator) {
|
||||||
level = 0;
|
level = 0;
|
||||||
internalFormat = GL_RGBA8;
|
internalFormat = GL_RGBA8;
|
||||||
data = pixels.ptr;
|
data = pixels.ptr;
|
||||||
@ -71,22 +109,51 @@ class Text {
|
|||||||
type = GL_UNSIGNED_BYTE;
|
type = GL_UNSIGNED_BYTE;
|
||||||
Allocate(texture_);
|
Allocate(texture_);
|
||||||
}
|
}
|
||||||
glyph_loaded_ = true;
|
|
||||||
|
indices_.Bind();
|
||||||
|
ElementArrayBufferAllocator indices_allcator;
|
||||||
|
with (indices_allcator) {
|
||||||
|
size = text.length * 6 * ushort.sizeof;
|
||||||
|
usage = GL_STATIC_DRAW;
|
||||||
|
Allocate(indices_);
|
||||||
|
}
|
||||||
|
auto indices_data = indices_.MapToWrite!ushort;
|
||||||
|
auto indices_ptr = indices_data.entity;
|
||||||
|
|
||||||
|
ushort vertex_count;
|
||||||
|
foreach (i; 0..text.length) {
|
||||||
|
*indices_ptr++ = vertex_count;
|
||||||
|
*indices_ptr++ = vertex_count++;
|
||||||
|
|
||||||
|
*indices_ptr++ = vertex_count++;
|
||||||
|
*indices_ptr++ = vertex_count++;
|
||||||
|
|
||||||
|
*indices_ptr++ = vertex_count;
|
||||||
|
*indices_ptr++ = vertex_count++;
|
||||||
|
}
|
||||||
|
index_count_ = indices_ptr - indices_data.entity;
|
||||||
|
|
||||||
|
return text_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
void Clear() {
|
||||||
|
index_count_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
void Draw(mat4 proj, mat4 view) {
|
void Draw(mat4 proj, mat4 view) {
|
||||||
if (!glyph_loaded_) return;
|
if (index_count_ == 0) return;
|
||||||
|
|
||||||
program_.Use(proj, view, matrix.Create(), texture_, color);
|
program_.Use(proj, view, matrix.Create(), texture_, color);
|
||||||
|
|
||||||
vao_.Bind();
|
vao_.Bind();
|
||||||
gl.DrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
indices_.Bind();
|
||||||
|
gl.DrawElements(GL_TRIANGLE_STRIP, index_count_.to!int, GL_UNSIGNED_SHORT, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
ModelMatrixFactory!4 matrix;
|
ModelMatrixFactory!4 matrix;
|
||||||
|
|
||||||
///
|
///
|
||||||
vec4 color = vec4(0, 0, 0, 1);
|
vec4 color = vec4(0, 0, 0, 1);
|
||||||
|
|
||||||
@ -109,5 +176,7 @@ class Text {
|
|||||||
|
|
||||||
ArrayBufferRef vertices_;
|
ArrayBufferRef vertices_;
|
||||||
|
|
||||||
bool glyph_loaded_ = false;
|
ElementArrayBufferRef indices_;
|
||||||
|
|
||||||
|
size_t index_count_;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user