Created
September 15, 2013 15:40
-
-
Save CapsAdmin/6571845 to your computer and use it in GitHub Desktop.
requires freetypegl compiled as a dll
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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