Skip to content

Instantly share code, notes, and snippets.

@CapsAdmin
Created September 15, 2013 15:40
Show Gist options
  • Save CapsAdmin/6571845 to your computer and use it in GitHub Desktop.
Save CapsAdmin/6571845 to your computer and use it in GitHub Desktop.
requires freetypegl compiled as a dll
local header = [[
typedef union
{
int data[4];
int x;
int y;
int z;
struct {
int w;
};
struct {
int x_;
int y_;
int width;
int height;
};
struct {
int r;
int g;
int b;
int a;
};
struct {
int red;
int green;
int blue;
int alpha;
};
struct {
int vstart;
int vcount;
int istart;
int icount;
};
} ivec4;
typedef union
{
int data[3];
struct {
int x;
int y;
int z;
};
struct {
int r;
int g;
int b;
};
struct {
int red;
int green;
int blue;
};
} ivec3;
typedef union
{
int data[2];
struct {
int x;
int y;
};
struct {
int s;
int t;
};
struct {
int start;
int end;
};
} ivec2;
typedef union
{
float data[4];
struct {
float x;
float y;
float z;
float w;
};
struct {
float x_;
float y_;
float width;
float height;
};
struct {
float r;
float g;
float b;
float a;
};
struct {
float red;
float green;
float blue;
float alpha;
};
} vec4;
typedef union
{
float data[3];
struct {
float x;
float y;
float z;
};
struct {
float r;
float g;
float b;
};
struct {
float red;
float green;
float blue;
};
} vec3;
typedef union
{
float data[2];
struct {
float x;
float y;
};
struct {
float s;
float t;
};
} vec2;
typedef union
{
float data[16];
struct {
float m00, m01, m02, m03;
float m10, m11, m12, m13;
float m20, m21, m22, m23;
float m30, m31, m32, m33;
};
} mat4;
typedef struct
{
void * items;
size_t capacity;
size_t size;
size_t item_size;
} vector_t;
typedef struct
{
vector_t * nodes;
size_t width;
size_t height;
size_t depth;
size_t used;
unsigned int id;
unsigned char * data;
} texture_atlas_t;
typedef struct {
texture_atlas_t * atlas;
vector_t * fonts;
wchar_t * cache;
} font_manager_t;
typedef struct
{
wchar_t charcode;
float kerning;
} kerning_t;
typedef struct
{
wchar_t charcode;
unsigned int id;
size_t width;
size_t height;
int offset_x;
int offset_y;
float advance_x;
float advance_y;
float s0;
float t0;
float s1;
float t1;
vector_t * kerning;
int outline_type;
float outline_thickness;
} texture_glyph_t;
typedef struct
{
vector_t * glyphs;
texture_atlas_t * atlas;
char * filename;
float size;
int hinting;
int outline_type;
float outline_thickness;
int filtering;
int kerning;
unsigned char lcd_weights[5];
float height;
float linegap;
float ascender;
float descender;
float underline_position;
float underline_thickness;
} texture_font_t;
typedef struct {
char * family;
float size;
int bold;
int italic;
float rise;
float spacing;
float gamma;
vec4 foreground_color;
vec4 background_color;
int outline;
vec4 outline_color;
int underline;
vec4 underline_color;
int overline;
vec4 overline_color;
int strikethrough;
vec4 strikethrough_color;
texture_font_t * font;
} markup_t;
typedef struct {
float x;
float y;
float z;
float u;
float v;
float r;
float g;
float b;
float a;
float shift;
float gamma;
} glyph_vertex_t;
typedef struct
{
GLchar * name;
GLuint index;
GLint size;
GLenum type;
GLboolean normalized;
GLsizei stride;
GLvoid * pointer;
void( * enable)(void * );
} vertex_attribute_t;
typedef struct
{
char * format;
vector_t * vertices;
GLuint vertices_id;
vector_t * indices;
GLuint indices_id;
size_t GPU_vsize;
size_t GPU_isize;
GLenum mode;
char state;
vector_t * items;
vertex_attribute_t * attributes[16];
} vertex_buffer_t;
typedef struct {
vertex_buffer_t * buffer;
font_manager_t * manager;
vec4 base_color;
vec2 origin;
size_t line_start;
float line_ascender;
float line_descender;
GLuint shader;
GLuint shader_texture;
GLuint shader_pixel;
} text_buffer_t;
mat4 * mat4_new(void);
void mat4_set_identity(mat4 * self);
void mat4_set_zero(mat4 * self);
void mat4_multiply(mat4 * self, mat4 * other);
void mat4_set_orthographic(mat4 * self,float left, float right,float bottom, float top,float znear, float zfar);
void mat4_set_perspective(mat4 * self,float fovy, float aspect,float zNear, float zFar);
void mat4_set_frustum(mat4 * self,float left, float right,float bottom, float top,float znear, float zfar);
void mat4_set_rotation(mat4 * self,float angle,float x, float y, float z);
void mat4_set_translation(mat4 * self,float x, float y, float z);
void mat4_set_scaling(mat4 * self,float x, float y, float z);
void mat4_rotate(mat4 * self,float angle,float x, float y, float z);
void mat4_translate(mat4 * self,float x, float y, float z);
void mat4_scale(mat4 * self, float x, float y, float z);
char * shader_read(const char * filename);
GLuint shader_compile(const char * source, const GLenum type);
GLuint shader_load(const char * vert_filename, const char * frag_filename);
GLuint shader_get(GLuint self, const char * name);
text_buffer_t * text_buffer_new(size_t depth);
void text_buffer_render(text_buffer_t * self);
void text_buffer_printf(text_buffer_t * self, vec2 * pen, ...);
void text_buffer_add_text(text_buffer_t * self, vec2 * pen, markup_t * markup, wchar_t * text, size_t length);
void text_buffer_add_wchar(text_buffer_t * self, vec2 * pen, markup_t * markup, wchar_t current, wchar_t previous);
void text_buffer_clear(text_buffer_t * self);
font_manager_t * font_manager_new(size_t width,size_t height,size_t depth);
void font_manager_delete(font_manager_t * self);
void font_manager_delete_font(font_manager_t * self,texture_font_t * font);
texture_font_t * font_manager_get_from_filename(font_manager_t * self,const char * filename,const float size);
texture_font_t * font_manager_get_from_description(font_manager_t * self,const char * family, const float size, const int bold, const int italic);
texture_font_t * font_manager_get_from_markup(font_manager_t * self,const markup_t * markup);
char * font_manager_match_description(font_manager_t * self,const char * family,const float size,const int bold,const int italic);
texture_atlas_t * texture_atlas_new(const size_t width,const size_t height,const size_t depth);
void texture_atlas_delete(texture_atlas_t * self);
void texture_atlas_upload(texture_atlas_t * self);
ivec4 texture_atlas_get_region(texture_atlas_t * self,const size_t width,const size_t height);
void texture_atlas_set_region(texture_atlas_t * self,const size_t x,const size_t y,const size_t width,const size_t height,const unsigned char * data,const size_t stride);
void texture_atlas_clear(texture_atlas_t * self);
vector_t * vector_new(size_t item_size);
void vector_delete(vector_t * self);
const void * vector_get(const vector_t * self, size_t index);
const void * vector_front(const vector_t * self);
const void * vector_back(const vector_t * self);
int vector_contains(const vector_t * self,const void * item,int( * cmp)(const void * , const void * ));
int vector_empty(const vector_t * self);
size_t vector_size(const vector_t * self);
void vector_reserve(vector_t * self,const size_t size);
size_t vector_capacity(const vector_t * self);
void vector_shrink(vector_t * self);
void vector_clear(vector_t * self);
void vector_set(vector_t * self,const size_t index,const void * item);
void vector_erase(vector_t * self,const size_t index);
void vector_erase_range(vector_t * self,const size_t first,const size_t last);
void vector_push_back(vector_t * self,const void * item);
void vector_pop_back(vector_t * self);
void vector_resize(vector_t * self,const size_t size);
void vector_insert(vector_t * self,const size_t index,const void * item);
void vector_insert_data(vector_t * self,const size_t index,const void * data,const size_t count);
void vector_push_back_data(vector_t * self,const void * data, const size_t count);
void vector_sort(vector_t * self, int( * cmp)(const void * , const void * ));
vertex_attribute_t * vertex_attribute_new(GLchar * name,GLint size,GLenum type,GLboolean normalized,GLsizei stride,GLvoid * pointer);
void vertex_attribute_delete(vertex_attribute_t * self);
vertex_attribute_t * vertex_attribute_parse(char * format);
void vertex_attribute_enable(vertex_attribute_t * attr);
vertex_buffer_t * vertex_buffer_new(const char * format);
void vertex_buffer_delete(vertex_buffer_t * self);
size_t vertex_buffer_size(const vertex_buffer_t * self);
const char * vertex_buffer_format(const vertex_buffer_t * self);
void vertex_buffer_print(vertex_buffer_t * self);
void vertex_buffer_render_setup(vertex_buffer_t * self, GLenum mode);
void vertex_buffer_render_finish(vertex_buffer_t * self);
void vertex_buffer_render(vertex_buffer_t * self, GLenum mode);
void vertex_buffer_render_item(vertex_buffer_t * self,size_t index);
void vertex_buffer_upload(vertex_buffer_t * self);
void vertex_buffer_clear(vertex_buffer_t * self);
void vertex_buffer_push_back_indices(vertex_buffer_t * self,const GLuint * indices,const size_t icount);
void vertex_buffer_push_back_vertices(vertex_buffer_t * self,const void * vertices,const size_t vcount);
void vertex_buffer_insert_indices(vertex_buffer_t * self,const size_t index,const GLuint * indices,const size_t icount);
void vertex_buffer_insert_vertices(vertex_buffer_t * self,const size_t index,const void * vertices,const size_t vcount);
void vertex_buffer_erase_indices(vertex_buffer_t * self,const size_t first,const size_t last);
void vertex_buffer_erase_vertices(vertex_buffer_t * self,const size_t first,const size_t last);
size_t vertex_buffer_push_back(vertex_buffer_t * self,const void * vertices, const size_t vcount, const GLuint * indices, const size_t icount);
size_t vertex_buffer_insert(vertex_buffer_t * self,size_t index,const void * vertices, const size_t vcount,const GLuint * indices, const size_t icount);
void vertex_buffer_erase(vertex_buffer_t * self,const size_t index);
texture_font_t * texture_font_new(texture_atlas_t * atlas, const char * filename,const float size);
void texture_font_delete(texture_font_t * self);
texture_glyph_t * texture_font_get_glyph(texture_font_t * self,wchar_t charcode);
size_t texture_font_load_glyphs(texture_font_t * self,const wchar_t * charcodes);
float texture_glyph_get_kerning(const texture_glyph_t * self,const wchar_t charcode);
texture_glyph_t * texture_glyph_new(void);
typedef struct {
float x, y, z; // position
float s, t; // texture
float r, g, b, a; // color
} vertex_t;
]]
ffi.cdef(header)
local lib = ffi.load("freetype-gl")
for line in header:gmatch("(.-)\n")do
local name = line:match("%L([%l_%d]-)%(")
if name then
name = name:trim()
--print(name)
end
end
local function add_text(buffer, font, text, color, pen)
local r,g,b,a = color:Unpack()
local last_char
for char in text:gmatch("(.)") do
char = ffi.cast("wchar_t", char)
local glyph = lib.texture_font_get_glyph(font, char)
if glyph then
local kerning = 0
if last_char then
kerning = lib.texture_glyph_get_kerning(glyph, last_char)
end
pen.x = pen.x + kerning;
local x0 = pen.x + glyph.offset_x
local y0 = pen.y + glyph.offset_y
local x1 = x0 + glyph.width
local y1 = y0 - glyph.height
local s0 = glyph.s0
local t0 = glyph.t0
local s1 = glyph.s1
local t1 = glyph.t1
local indices = ffi.new("GLuint[6]", {0,1,2, 0,2,3})
local vertices = ffi.new("vertex_t[4]", {
{ x0,y0,0, s0,t0, r,g,b,a },
{ x0,y1,0, s0,t1, r,g,b,a },
{ x1,y1,0, s1,t1, r,g,b,a },
{ x1,y0,0, s1,t0, r,g,b,a }
}
)
lib.vertex_buffer_push_back(buffer, vertices, 4, indices, 6)
pen.x = pen.x + glyph.advance_x
end
last_char = char
end
end
local atlas = lib.texture_atlas_new(512, 512, 1)
local buffer = lib.vertex_buffer_new("vertex:3f,tex_coord:2f,color:4f")
local pen = Vec2(5, 400)
local black = Color(1,0,1,1)
local text = "A Quick Brown Fox Jumps Over The Lazy Dog 0123456789"
local filename = R"fonts/arial.ttf"
for i = 7, 27 do
local font = lib.texture_font_new(atlas, filename, i)
pen.x = 5
pen.y = pen.y - font.height
lib.texture_font_load_glyphs(font, ffi.cast("const wchar_t*", text))
add_text(buffer, font, text, black, pen)
lib.texture_font_delete(font)
end
gl.ClearColor(0.5,0.5,0.5,1)
local window = glw.OpenWindow(1280, 720)
print(atlas.id)
event.AddListener("OnDraw", "gl", function(dt)
render.Start(window)
render.Clear(e.GL_COLOR_BUFFER_BIT, e.GL_DEPTH_BUFFER_BIT)
surface.Start()
gl.BindTexture(e.GL_TEXTURE_2D, atlas.id)
surface.DrawRect(0, 0, 512, 512)
render.End()
end)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment