From: Brendan Hansen Date: Tue, 22 Sep 2020 04:00:02 +0000 (-0500) Subject: font rendering works! kinda X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=c8c5d69179e12a159c152e27cc1a2d7855786379;p=onyx-game.git font rendering works! kinda --- diff --git a/js/environment.js b/js/environment.js index 84d0bb9..17d8e53 100644 --- a/js/environment.js +++ b/js/environment.js @@ -49,6 +49,8 @@ return { game: { launch: start_game }, + dummy: { breakable() { debugger; }, }, + event: { setup(esp, event_size) { // Indicies into a Uint32Array are not based on bytes, diff --git a/res/Hack-Regular.ttf b/res/Hack-Regular.ttf new file mode 100644 index 0000000..92a90cb Binary files /dev/null and b/res/Hack-Regular.ttf differ diff --git a/src/font.onyx b/src/font.onyx index eb0e3d4..855cae7 100644 --- a/src/font.onyx +++ b/src/font.onyx @@ -118,6 +118,22 @@ TrueTypeFont :: struct { font_direction_hint : i16; index_to_loc_format : TTIndexToLocFormat; glyph_data_format : i16; + + hhea : struct { + version : u32; + ascent : i16; + descent : i16; + line_gap : i16; + advance_width_max : u16; + min_left_side_bearing : i16; + min_right_side_bearing : i16; + x_max_extent : i16; + caret_slope_rise : i16; + caret_slope_run : i16; + caret_offset : i16; + metric_data_format : i16; + num_of_long_hor_metrics : u16; + }; } TTTableInfo :: struct { @@ -154,6 +170,9 @@ ttf_create :: proc (ttf_data: [] u8) -> TrueTypeFont { i32map_init(^ttf.table_map); array_init(^ttf.char_maps); ttf_read_offset_table(^ttf); + ttf_read_head_table(^ttf); + ttf_read_cmap_table(^ttf); + ttf_read_hhea_table(^ttf); return ttf; } @@ -178,7 +197,6 @@ ttf_read_offset_table :: proc (use ttf: ^TrueTypeFont) { i32map_put(^table_map, tag_int, table_info); if !string_equal(tag, "head") { - // TODO: Calculate checksum to ensure everything looks right csum := ttf_calc_table_checksum(^reader, table_info.offset, table_info.length); if table_info.checksum != csum { print("WARNING: Checksum for table '"); @@ -266,6 +284,12 @@ ttf_read_glyph :: proc (use ttf: ^TrueTypeFont, glyph_index: i32) -> ^TTGlyph { return glyph; } +ttf_glyph_destroy :: proc (glyph: ^TTGlyph) { + array_free(^glyph.contour_ends); + array_free(^glyph.points); + cfree(glyph); +} + #private_file TTGlyphFlags :: enum #flags { On_Curve :: 0x01; @@ -432,7 +456,7 @@ ttf_read_cmap0 :: proc (use ttf: ^TrueTypeFont) { cmap.cmap0.format = TTCmapFormat.Simple; glyphs : [..] u8; - array_init(^glyphs, 256); + array_init(^glyphs, 256); for i: 0 .. 256 do array_push(^glyphs, read_u8(^reader)); cmap.cmap0.glyph_indicies = array_to_slice(^glyphs); @@ -444,6 +468,7 @@ ttf_read_cmap4 :: proc (use ttf: ^TrueTypeFont) { cmap : TTCmap; cmap.cmap4.format = TTCmapFormat.Segmented; map := ^cmap.cmap4; + i32map_init(^map.cache); map.seg_count = read_u16(^reader) >> ~~1; map.search_range = read_u16(^reader); @@ -488,7 +513,7 @@ ttf_lookup_in_cmap0 :: proc (use ttf: ^TrueTypeFont, cmap: ^TTCmap0, charcode: u #private_file ttf_lookup_in_cmap4 :: proc (use ttf: ^TrueTypeFont, cmap: ^TTCmap4, charcode: u32) -> u32 { - // TODO: Lookup in the cache + if i32map_has(^cmap.cache, charcode) do return i32map_get(^cmap.cache, charcode); index := 0; for ^seg: cmap.segments { @@ -505,9 +530,228 @@ ttf_lookup_in_cmap4 :: proc (use ttf: ^TrueTypeFont, cmap: ^TTCmap4, charcode: u } } + i32map_put(^cmap.cache, charcode, index); + return index; } +ttf_read_hhea_table :: proc (use ttf: ^TrueTypeFont) { + empty_table_hack := TTTableInfo.{}; + hhea_table_info := i32map_get(^table_map, string_to_beu32("hhea"), empty_table_hack); + seek(^reader, hhea_table_info.offset); + + hhea.version = read_u32(^reader); + hhea.ascent = read_fword(^reader); + hhea.descent = read_fword(^reader); + hhea.line_gap = read_fword(^reader); + hhea.advance_width_max = read_u16(^reader); + hhea.min_left_side_bearing = read_u16(^reader); + hhea.min_right_side_bearing = read_u16(^reader); + hhea.x_max_extent = read_fword(^reader); + hhea.caret_slope_rise = read_i16(^reader); + hhea.caret_slope_run = read_i16(^reader); + hhea.caret_offset = read_fword(^reader); + read_i16(^reader); // Reserved + read_i16(^reader); // Reserved + read_i16(^reader); // Reserved + read_i16(^reader); // Reserved + hhea.metric_data_format = read_i16(^reader); + hhea.num_of_long_hor_metrics = read_u16(^reader); +} + +TTHorizontalMetrics :: struct { + advance_width : u16; + left_side_bearing : i16; +} + +ttf_lookup_horizontal_metrics :: proc (use ttf: ^TrueTypeFont, glyph_index: u32) -> TTHorizontalMetrics { + empty_table_hack := TTTableInfo.{}; + hmtx_table_info := i32map_get(^table_map, string_to_beu32("hmtx"), empty_table_hack); + offset := hmtx_table_info.offset; + + hmtx : TTHorizontalMetrics; + + nmets := cast(u32) hhea.num_of_long_hor_metrics; + + if glyph_index < nmets { + offset += glyph_index * 4; + old := seek(^reader, offset); + defer seek(^reader, old); + + hmtx.advance_width = read_u16(^reader); + hmtx.left_side_bearing = read_i16(^reader); + + } else { + old := seek(^reader, offset + (nmets - 1) * 4); + defer seek(^reader, old); + + hmtx.advance_width = read_u16(^reader); + seek(^reader, offset + nmets * 4 + 2 * (glyph_index - nmets)); + hmtx.left_side_bearing = read_i16(^reader); + } + + return hmtx; +} + + +// Renders a grayscale image +// To be used with gl.LUMANIANCE +ttf_render_glyph :: proc (use ttf: ^TrueTypeFont, glyph: ^TTGlyph, data: ^u8, width: u32, height: u32) { + // Black background + for y: 0 .. height do for x: 0 .. width do data[x + y * width] = cast(u8) 0; + + scale := cast(f32) height / ~~cast(i32) units_per_em; + + state := 0; + count := 0; + contour_start := 0; + + curr_x := 0; + curr_y := 0; + + poly_points : [..] V2i; + array_init(^poly_points, 16); + defer array_free(^poly_points); + + for i: 0 .. glyph.points.count { + p := glyph.points[i]; + + + switch state { + case 0 { + // curr_x = cast(i32) p.x; + // curr_y = cast(i32) p.y; + + array_push(^poly_points, V2i.{ ~~p.x, ~~p.y }); + state = 1; + } + + case 1 do if p.on_curve { + // draw_line(data, width, height, scale, + // curr_x, curr_y, + // ~~p.x, ~~p.y); + + // curr_x = cast(i32) p.x; + // curr_y = cast(i32) p.y; + array_push(^poly_points, V2i.{ ~~p.x, ~~p.y }); + + } else { + state = 2; + } + + case #default { + prev := glyph.points[i - 1]; + if p.on_curve { + // draw_quadratic_line(data, width, height, scale, + // curr_x, curr_y, + // ~~prev.x, ~~prev.y, + // ~~p.x, ~~p.y); + + // curr_x = cast(i32) p.x; + // curr_y = cast(i32) p.y; + // array_push(^poly_points, V2i.{ ~~prev.x, ~~prev.y }); + array_push(^poly_points, V2i.{ ~~p.x, ~~p.y }); + state = 1; + + } else { + //draw_quadratic_line(data, width, height, scale, + // curr_x, curr_y, + // ~~prev.x, ~~prev.y, + // ~~((prev.x + p.x) / ~~2), ~~((prev.y + p.y) / ~~2)); + + //curr_x = cast(i32) ((prev.x + p.x) / ~~2); + //curr_y = cast(i32) ((prev.y + p.y) / ~~2); + array_push(^poly_points, V2i.{ ~~prev.x, ~~prev.y }); + array_push(^poly_points, V2i.{ ~~((prev.x + p.x) / ~~2), ~~((prev.y + p.y) / ~~2) }); + } + } + } + + if i == ~~glyph.contour_ends[count] { + prev := p; + p = glyph.points[contour_start]; + + if p.on_curve { + // draw_quadratic_line(data, width, height, scale, + // curr_x, curr_y, + // ~~prev.x, ~~prev.y, + // ~~p.x, ~~p.y); + + // curr_x = cast(i32) p.x; + // curr_y = cast(i32) p.y; + array_push(^poly_points, V2i.{ ~~prev.x, ~~prev.y }); + + } else { + // draw_quadratic_line(data, width, height, scale, + // curr_x, curr_y, + // ~~prev.x, ~~prev.y, + // ~~((prev.x + p.x) / ~~2), ~~((prev.y + p.y) / ~~2)); + + // curr_x = cast(i32) ((prev.x + p.x) / ~~2); + // curr_y = cast(i32) ((prev.y + p.y) / ~~2); + array_push(^poly_points, V2i.{ ~~prev.x, ~~prev.y }); + array_push(^poly_points, V2i.{ ~~((prev.x + p.x) / ~~2), ~~((prev.y + p.y) / ~~2) }); + } + + contour_start = i + 1; + count += 1; + state = 0; + + + // col := cast(u8) 255; + // if v2_orientation(poly_points[0], poly_points[1], poly_points[2]) < 0 do col = cast(u8) 0; + + for p: poly_points do print_vec(p); + for y: 0 .. height do for x: 0 .. width { + if is_inside_polygon(array_to_slice(^poly_points), V2i.{ ~~(~~x / scale), ~~(~~y / scale) }) { + curr := data[x + (height - 1 - y) * width]; + if curr == ~~0 do data[x + (height - 1 - y) * width] = cast(u8) 255; + else do data[x + (height - 1 - y) * width] = cast(u8) 0; + } + } + + array_clear(^poly_points); + } + } +} + +#private_file +draw_line :: proc (data: ^u8, width: u32, height: u32, scale: f32, x0: u32, y0: u32, x1: u32, y1: u32) { + start := V2i.{ x0, y0 }; + end := V2i.{ x1, y1 }; + dist := sqrt_f32(~~v2_square_dist(start, end)); + + for t: 0 .. ~~dist { + p := v2_lerp(~~t / dist, start, end); + px := cast(i32) (~~p.x * scale); + py := cast(i32) (~~p.y * scale); + if px >= 0 && py >= 0 && px < width && py < height { + data[px + (height - 1 - py) * width] = cast(u8) 255; + } + } +} + +#private_file +draw_quadratic_line :: proc (data: ^u8, width: u32, height: u32, scale: f32, x0: u32, y0: u32, x1: u32, y1: u32, x2: u32, y2: u32) { + // draw_line(data, width, height, scale, x0, y0, x1, y1); + // draw_line(data, width, height, scale, x1, y1, x2, y2); + + points : [3] V2f; + points[0] = V2f.{ ~~x0, ~~y0 }; + points[1] = V2f.{ ~~x1, ~~y1 }; + points[2] = V2f.{ ~~x2, ~~y2 }; + + for t: 0 .. 200 { + p := bezier_curve(~~t / 200.0f, points[0 .. 3]); + + px := cast(i32) (~~p.x * scale); + py := cast(i32) (~~p.y * scale); + if px >= 0 && py >= 0 && px < width && py < height { + data[px + (height - 1 - py) * width] = cast(u8) 255; + } + } +} + #private_file ttf_calc_table_checksum :: proc (reader: ^BinaryReader, offset: u32, length: u32) -> u32 { old := seek(reader, offset); diff --git a/src/gfx/texture.onyx b/src/gfx/texture.onyx index a3475ae..74c601d 100644 --- a/src/gfx/texture.onyx +++ b/src/gfx/texture.onyx @@ -6,44 +6,51 @@ use package gl_utils as gl_utils Color3 :: struct { r: u8; g: u8; b: u8; } +#private_file current_tex_id := 0; + Texture :: struct { // NOTE: After a texture is loaded, we may not want to keep the // raw texture data in memory any longer. This would not be possible // if it is stored in the data section. - data : [] Color3; + data : [] u8; width : i32; height : i32; + data_mode : TextureDataMode; + texture_id : gl.GLTexture; } +TextureDataMode :: enum { + RGB :: 0x01; + BRIGHTNESS :: 0x02; +} + // NOTE: This assumes that the data is raw u8 RGB packed color data. -texture_create :: proc (texdata: [] Color3, width: i32, height: i32) -> Texture { +texture_create :: proc (texdata: [] u8, width: i32, height: i32, data_mode := TextureDataMode.RGB) -> Texture { tex : Texture; tex.data = texdata; tex.width = width; tex.height = height; + tex.data_mode = data_mode; tex.texture_id = -1; - if width * height != tex.data.count { - println("Warning: Texture width and height does not match the size of data given."); - } - return tex; } texture_prepare :: proc (use tex: ^Texture) { if texture_id != -1 do return; - texdata := (cast(^u8) data.data)[0 .. data.count * 3]; + format := gl.RGB; + if data_mode == TextureDataMode.BRIGHTNESS do format = gl.LUMINANCE; texture_id = gl.createTexture(); - gl.activeTexture(gl.TEXTURE0); + // gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, texture_id); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, width, height, 0, gl.RGB, gl.UNSIGNED_BYTE, texdata); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); - gl.bindTexture(gl.TEXTURE_2D, -1); + gl.texImage2D(gl.TEXTURE_2D, 0, format, width, height, 0, format, gl.UNSIGNED_BYTE, data); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + // gl.bindTexture(gl.TEXTURE_2D, -1); } texture_use :: proc (use tex: ^Texture) { diff --git a/src/main.onyx b/src/main.onyx index 6a94bcc..72c3ceb 100644 --- a/src/main.onyx +++ b/src/main.onyx @@ -58,6 +58,8 @@ draw_rect :: proc (use rc: ^RenderContext, x: f32, y: f32, w: f32, h: f32) { pos = Vec2.{ x, y }, size = Vec2.{ w, h }, color = color, + + tex_size = Vec2.{ 1.0f, 1.0f }, }); curr_quad_idx += 1; @@ -67,6 +69,8 @@ render_context_flush :: proc (use rc: ^RenderContext) { quad_rebuffer_data(quad_renderer); quad_renderer_draw(quad_renderer); + for i: 0 .. curr_quad_idx do quad_update_at_index(quad_renderer, i, Quad.{}); + curr_quad_idx = 0; } @@ -79,6 +83,8 @@ window_height := 0 renderer : RenderContext input_state : input.InputState ttf : TrueTypeFont +font_tex : Texture +smile : Texture Player :: struct { use pos : Vec2; } player : Player @@ -120,44 +126,55 @@ update :: proc () { if input.key_down(^input_state, Key.ArrowRight) do player.x += player_speed; } -draw :: proc () { - defer render_context_flush(^renderer); +glyph_size :: 128 +glyph_data : [glyph_size * glyph_size] u8 +draw :: proc () { gl.clearColor(0.2f, 0.2f, 0.2f, 1.0f); + // gl.clearColor(1.0f, 1.0f, 1.0f, 1.0f); gl.clear(gl.COLOR_BUFFER_BIT); - renderer.color = Color4f32.{ 1f, 0f, 0f, 1f }; + // renderer.color = Color4f32.{ 1f, 0f, 0f, 1f }; - points : [6] V2f; - points[0] = V2f.{ 500.0f, 700.0f }; - points[1] = V2f.{ 600.0f, 200.0f }; - points[2] = V2f.{ 700.0f, 400.0f }; - points[3] = V2f.{ 1700.0f, 800.0f }; - points[4] = V2f.{ 1800.0f, 400.0f }; - points[5] = V2f.{ 1000.0f, 200.0f }; + // points : [6] V2f; + // points[0] = V2f.{ 500.0f, 700.0f }; + // points[1] = V2f.{ 600.0f, 200.0f }; + // points[2] = V2f.{ 700.0f, 400.0f }; + // points[3] = V2f.{ 1700.0f, 800.0f }; + // points[4] = V2f.{ 1800.0f, 400.0f }; + // points[5] = V2f.{ 1000.0f, 200.0f }; - for i: 0 .. 200 { - pos := bezier_curve(~~i / 200.0f, points[0 .. 6]); - draw_rect(^renderer, pos.x, pos.y, 16f, 16f); - } + // for i: 0 .. 200 { + // pos := bezier_curve(~~i / 200.0f, points[0 .. 6]); + // draw_rect(^renderer, pos.x, pos.y, 16f, 16f); + // } - glyph : ^TTGlyph = null; - glyph_index := ttf_lookup_glyph_by_char(^ttf, ~~ #char "A"); - glyph = ttf_read_glyph(^ttf, glyph_index); - defer cfree(glyph); - defer array_free(^glyph.points); - defer array_free(^glyph.contour_ends); - - rx := 100.0f / ~~ cast(i32) (glyph.x_max - glyph.x_min); - ry := 100.0f / ~~ cast(i32) (glyph.y_min - glyph.y_max); - for p: glyph.points { - // if p.on_curve do continue; - draw_rect(^renderer, ~~ cast(i32) p.x * rx + 100f, ~~ cast(i32) p.y * ry + 100f, 10f, 10f); - } + // for y: 0 .. glyph_size do for x: 0 .. glyph_size { + // if glyph_data[x + y * glyph_size] != ~~0 { + // draw_rect(^renderer, ~~(x * 2 + 100), ~~(y * 2 + 100), 2f, 2f); + // } + // } + + // mets := ttf_lookup_horizontal_metrics(^ttf, glyph_index); + // println(cast(u32) mets.advance_width); - draw_rect(^renderer, ~~input_state.mouse.x, ~~input_state.mouse.y, 10f, 10f); + // rx := 100.0f / ~~ cast(i32) (glyph.x_max - glyph.x_min); + // ry := 100.0f / ~~ cast(i32) (glyph.y_min - glyph.y_max); + // for p: glyph.points { + // if p.on_curve do continue; + // draw_rect(^renderer, ~~ cast(i32) p.x * rx + 100f, ~~ cast(i32) p.y * ry + 100f, 10f, 10f); + // } + + + texture_use(^smile); + draw_rect(^renderer, ~~input_state.mouse.x, ~~input_state.mouse.y, 100f, 100f); draw_rect(^renderer, player.pos.x, player.pos.y, 100f, 100f); + render_context_flush(^renderer); + + texture_use(^font_tex); + draw_rect(^renderer, 100f, 100f, 64f, 64f); + render_context_flush(^renderer); } // This procedure is called asynchronously from JS every frame. @@ -182,39 +199,25 @@ main :: proc (args: [] cstring) { render_context_init(^renderer, null); - // CLEANUP: Maybe there should be a way to cast between slices? - // Automatically multiply / divide the count by the ratio of the type sizes? - // This could be very buggy - raw_image_data := #file_contents "res/smile.data"; - image_data := (cast(^Color3) raw_image_data.data)[0 .. raw_image_data.count / 3]; - - smile := texture_create(image_data, 32, 32); + image_data := #file_contents "res/smile.data"; + smile = texture_create(image_data, 32, 32); texture_prepare(^smile); - texture_use(^smile); event.init(); input.init(^input_state); - ttf_data := #file_contents "res/Inconsolata-Regular.ttf"; + ttf_data := #file_contents "res/Hack-Regular.ttf"; ttf = ttf_create(ttf_data); - ttf_read_head_table(^ttf); - ttf_read_cmap_table(^ttf); - - // for i: 0 .. ttf_glyph_count(^ttf) { - // glyph := ttf_read_glyph(^ttf, i); - // if glyph == null do continue; - // defer cfree(glyph); - - // // println(glyph.points.count); - // // for p: glyph.points { - // // print(p.on_curve); - // // print(" "); - // // print(cast(i32) p.x); - // // print(", "); - // // print(cast(i32) p.y); - // // print("\n"); - // // } - // } + + glyph : ^TTGlyph = null; + glyph_index := ttf_lookup_glyph_by_char(^ttf, ~~ #char "%"); + glyph = ttf_read_glyph(^ttf, glyph_index); + if glyph == null do return; + defer ttf_glyph_destroy(glyph); + + ttf_render_glyph(^ttf, glyph, ~~glyph_data, glyph_size, glyph_size); + font_tex = texture_create(glyph_data[0 .. glyph_size * glyph_size], glyph_size, glyph_size, TextureDataMode.BRIGHTNESS); + texture_prepare(^font_tex); game_launch(); } diff --git a/src/vecmath.onyx b/src/vecmath.onyx index 0d638e0..034a48e 100644 --- a/src/vecmath.onyx +++ b/src/vecmath.onyx @@ -1,5 +1,7 @@ package vecmath +use package core + // BUG: Default values do not work on polymorphic structs. V2 :: struct ($T) { x: T; y: T; } @@ -26,3 +28,82 @@ v2_mul :: proc (a: V2($T), scalar: T) -> V2(T) { ret.y = a.y * scalar; return ret; } + +v2_lerp :: proc (t: f32, start: V2($T), end: V2(T)) -> V2(T) { + ret : V2(T); + ret.x = ~~(t * ~~(end.x - start.x)) + start.x; + ret.y = ~~(t * ~~(end.y - start.y)) + start.y; + return ret; +} + +v2_square_dist :: proc (a: V2($T), b: V2(T)) -> T { + return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y); +} + +// -1 for counter-clockwise +// 0 for colinear +// 1 for clockwise +v2_orientation :: proc (a: V2($T), b: V2(T), c: V2(T)) -> i32 { + val := (b.y - a.y) * (c.x - b.x) - (b.x - a.x) * (c.y - b.y); + if val == ~~0 do return 0; + if val > ~~0 do return 1; + return -1; +} + +// assumes a b and c are colinear +v2_on_segment :: proc (a: V2($T), b: V2(T), c: V2(T)) -> bool { + return b.x <= max_poly(a.x, c.x) + && b.x >= min_poly(a.x, c.x) + && b.y <= max_poly(a.y, c.y) + && b.y >= min_poly(a.y, c.y); +} + + +lines_intersect :: proc (p1: V2($T), q1: V2(T), p2: V2(T), q2: V2(T)) -> bool { + o1 := v2_orientation(p1, q1, p2); + o2 := v2_orientation(p1, q1, q2); + o3 := v2_orientation(p2, q2, p1); + o4 := v2_orientation(p2, q2, q1); + + if o1 != o2 && o3 != o4 do return true; + + if o1 == 0 && v2_on_segment(p1, p2, q1) do return true; + if o2 == 0 && v2_on_segment(p1, q2, q1) do return true; + if o3 == 0 && v2_on_segment(p2, p1, q2) do return true; + if o4 == 0 && v2_on_segment(p2, q1, q2) do return true; + + return false; +} + +is_inside_polygon :: proc (polygon: [] V2($T), p: V2(T)) -> bool { + if polygon.count < 3 do return false; + + extreme : V2(T); + extreme.x = cast(T) 1000000; // Needs be infinity... close enough + extreme.y = p.y; + + count := 0; + for i: 0 .. polygon.count { + next := (i + 1) % polygon.count; + + if lines_intersect(polygon[i], polygon[next], p, extreme) { + if v2_orientation(polygon[i], p, polygon[next]) == 0 { + return v2_on_segment(polygon[i], p, polygon[next]); + } + + count += 1; + } + } + + return (count % 2) == 1; +} + + + +print_vec :: proc (v: V2($T)) { + print("V2("); + print(v.x); + print(", "); + print(v.y); + println(")"); +} diff --git a/tags b/tags index f9f074e..96bdeda 100644 --- a/tags +++ b/tags @@ -565,10 +565,12 @@ TTCmapBase src/font.onyx /^TTCmapBase :: struct { format : TTCmapFormat; }$/ TTCmapFormat src/font.onyx /^TTCmapFormat :: enum (u16) {$/ TTGlyph src/font.onyx /^TTGlyph :: struct {$/ TTGlyphPoint src/font.onyx /^TTGlyphPoint :: struct {$/ +TTHorizontalMetrics src/font.onyx /^TTHorizontalMetrics :: struct {$/ TTIndexToLocFormat src/font.onyx /^TTIndexToLocFormat :: enum (i16) {$/ TTSegment src/font.onyx /^TTSegment :: struct {$/ TTTableInfo src/font.onyx /^TTTableInfo :: struct {$/ Texture src/gfx/texture.onyx /^Texture :: struct {$/ +TextureDataMode src/gfx/texture.onyx /^TextureDataMode :: enum {$/ TrueTypeFont src/font.onyx /^TrueTypeFont :: struct {$/ UNIFORM_ARRAY_STRIDE /usr/share/onyx/core/js/webgl.onyx /^UNIFORM_ARRAY_STRIDE :: 0x8A3C$/ UNIFORM_BLOCK_ACTIVE_UNIFORMS /usr/share/onyx/core/js/webgl.onyx /^UNIFORM_BLOCK_ACTIVE_UNIFORMS :: 0x8A42$/ @@ -744,6 +746,7 @@ finish /usr/share/onyx/core/js/webgl.onyx /^finish :: pr floor_f32 /usr/share/onyx/core/intrinsics.onyx /^floor_f32 :: proc (val: f32) -> f32 #intrinsic ---$/ floor_f64 /usr/share/onyx/core/intrinsics.onyx /^floor_f64 :: proc (val: f64) -> f64 #intrinsic ---$/ flush /usr/share/onyx/core/js/webgl.onyx /^flush :: proc () #foreign "gl" "flush" ---$/ +font_tex src/main.onyx /^font_tex : Texture$/ framebufferRenderbuffer /usr/share/onyx/core/js/webgl.onyx /^framebufferRenderbuffer :: proc (target: GLenum, attachment: GLenum, renderbuffertarget: GLenum, renderbuffer: GLRenderbuffer) #foreign "gl" "framebufferRenderbuffer" ---$/ framebufferTexture2D /usr/share/onyx/core/js/webgl.onyx /^framebufferTexture2D :: proc (target: GLenum, attachment: GLenum, textarget: GLenum, texture: GLTexture, level: GLint) #foreign "gl" "framebufferTexture2D" ---$/ framebufferTextureLayer /usr/share/onyx/core/js/webgl.onyx /^framebufferTextureLayer :: proc (target: GLenum, attachment: GLenum, texture: GLTexture, level: GLint, layer: GLint) #foreign "gl" "framebufferTextureLayer" ---$/ @@ -761,6 +764,8 @@ getProgramParameter /usr/share/onyx/core/js/webgl.onyx /^getProgramParameter getShaderParameter /usr/share/onyx/core/js/webgl.onyx /^getShaderParameter :: proc (shader: GLShader, pname: GLenum) -> GLenum #foreign "gl" "getShaderParameter" ---$/ getUniformLocation /usr/share/onyx/core/js/webgl.onyx /^getUniformLocation :: proc (program: GLProgram, name: string) -> GLUniformLocation #foreign "gl" "getUniformLocation" ---$/ getVertexAttribOffset /usr/share/onyx/core/js/webgl.onyx /^getVertexAttribOffset :: proc (index: GLuint, pname: GLenum) #foreign "gl" "getVertexAttribOffset" ---$/ +glyph_data src/main.onyx /^glyph_data : [glyph_size * glyph_size] u8$/ +glyph_size src/main.onyx /^glyph_size :: 128$/ heap_alloc /usr/share/onyx/core/alloc.onyx /^heap_alloc :: proc (size_: u32, align: u32) -> rawptr {$/ heap_alloc_proc /usr/share/onyx/core/alloc.onyx /^heap_alloc_proc :: proc (data: rawptr, aa: AllocAction, size: u32, align: u32, oldptr: rawptr) -> rawptr {$/ heap_allocator /usr/share/onyx/core/alloc.onyx /^heap_allocator : Allocator;$/ @@ -785,10 +790,12 @@ input_state src/main.onyx /^input_state : input.InputState$/ invalidateFramebuffer /usr/share/onyx/core/js/webgl.onyx /^invalidateFramebuffer :: proc (target: GLenum, attachments: string) #foreign "gl" "invalidateFramebuffer" ---$/ invalidateSubFramebuffer /usr/share/onyx/core/js/webgl.onyx /^invalidateSubFramebuffer :: proc (target: GLenum, attachments: string, x: GLint, y: GLint, width: GLsizei, height: GLsizei) #foreign "gl" "invalidateSubFramebuffer" ---$/ isEnabled /usr/share/onyx/core/js/webgl.onyx /^isEnabled :: proc (cap: GLenum) -> GLboolean #foreign "gl" "isEnabled" ---$/ +is_inside_polygon src/vecmath.onyx /^is_inside_polygon :: proc (polygon: [] V2($T), p: V2(T)) -> bool {$/ key_down src/input.onyx /^key_down :: proc (use state: ^InputState, key: Key) -> bool {$/ key_just_down src/input.onyx /^key_just_down :: proc (use state: ^InputState, key: Key) -> bool {$/ key_up src/input.onyx /^key_up :: proc (use state: ^InputState, key: Key) -> bool {$/ lineWidth /usr/share/onyx/core/js/webgl.onyx /^lineWidth :: proc (width: GLfloat) #foreign "gl" "lineWidth" ---$/ +lines_intersect src/vecmath.onyx /^lines_intersect :: proc (p1: V2($T), q1: V2(T), p2: V2(T), q2: V2(T)) -> bool {$/ linkProgram /usr/share/onyx/core/js/webgl.onyx /^linkProgram :: proc (program: GLProgram) #foreign "gl" "linkProgram" ---$/ link_program src/utils/gl.onyx /^link_program :: proc (vertex_shader: gl.GLShader, frag_shader: gl.GLShader) -> gl.GLProgram {$/ main src/main.onyx /^main :: proc (args: [] cstring) {$/ @@ -830,6 +837,7 @@ print_i64 /usr/share/onyx/core/stdio.onyx /^print_i64 :: proc (n: i64, base print_ptr /usr/share/onyx/core/stdio.onyx /^print_ptr :: proc (p: ^void) do string_builder_append(^print_buffer, cast(i64) p, 16l);$/ print_range /usr/share/onyx/core/stdio.onyx /^print_range :: proc (r: range, sep := " ") {$/ print_string /usr/share/onyx/core/stdio.onyx /^print_string :: proc (s: string) {$/ +print_vec src/vecmath.onyx /^print_vec :: proc (v: V2($T)) {$/ println /usr/share/onyx/core/stdio.onyx /^println :: proc (x: $T) {$/ process_event src/input.onyx /^process_event :: proc (use state: ^InputState, ev: ^event.Event) {$/ ptrmap_clear /usr/share/onyx/core/ptrmap.onyx /^ptrmap_clear :: proc (use pmap: ^PtrMap) {$/ @@ -874,8 +882,10 @@ shl_i64 /usr/share/onyx/core/intrinsics.onyx /^shl_i64 :: proc (lhs: i64, r sin /usr/share/onyx/core/math.onyx /^sin :: proc (t_: f32) -> f32 {$/ slr_i32 /usr/share/onyx/core/intrinsics.onyx /^slr_i32 :: proc (lhs: i32, rhs: i32) -> i32 #intrinsic ---$/ slr_i64 /usr/share/onyx/core/intrinsics.onyx /^slr_i64 :: proc (lhs: i64, rhs: i64) -> i64 #intrinsic ---$/ +smile src/main.onyx /^smile : Texture$/ sqrt_f32 /usr/share/onyx/core/intrinsics.onyx /^sqrt_f32 :: proc (val: f32) -> f32 #intrinsic ---$/ sqrt_f64 /usr/share/onyx/core/intrinsics.onyx /^sqrt_f64 :: proc (val: f64) -> f64 #intrinsic ---$/ +sqrt_i32 /usr/share/onyx/core/math.onyx /^sqrt_i32 :: proc (x: i32) -> i32 {$/ stdio_init /usr/share/onyx/core/stdio.onyx /^stdio_init :: proc () {$/ stencilFunc /usr/share/onyx/core/js/webgl.onyx /^stencilFunc :: proc (func: GLenum, ref: GLint, mask: GLuint) #foreign "gl" "stencilFunc" ---$/ stencilFuncSeparate /usr/share/onyx/core/js/webgl.onyx /^stencilFuncSeparate :: proc (face: GLenum, func: GLenum, ref: GLint, mask: GLuint) #foreign "gl" "stencilFuncSeparate" ---$/ @@ -911,7 +921,7 @@ texImage2D /usr/share/onyx/core/js/webgl.onyx /^texImage2D : texParameterf /usr/share/onyx/core/js/webgl.onyx /^texParameterf :: proc (target: GLenum, pname: GLenum, param: GLfloat) #foreign "gl" "texParameterf" ---$/ texParameteri /usr/share/onyx/core/js/webgl.onyx /^texParameteri :: proc (target: GLenum, pname: GLenum, param: GLint) #foreign "gl" "texParameteri" ---$/ texSubImage2D /usr/share/onyx/core/js/webgl.onyx /^texSubImage2D :: proc (target: GLenum, level: GLint, xoff: GLint, yoff: GLint, width: GLsizei, height: GLsizei, format: GLenum, type: GLenum, pixels: string) #foreign "gl" "texSubImage2D" ---$/ -texture_create src/gfx/texture.onyx /^texture_create :: proc (texdata: [] Color3, width: i32, height: i32) -> Texture {$/ +texture_create src/gfx/texture.onyx /^texture_create :: proc (texdata: [] u8, width: i32, height: i32, data_mode := TextureDataMode.RGB) -> Texture {$/ texture_prepare src/gfx/texture.onyx /^texture_prepare :: proc (use tex: ^Texture) {$/ texture_use src/gfx/texture.onyx /^texture_use :: proc (use tex: ^Texture) {$/ trunc_f32 /usr/share/onyx/core/intrinsics.onyx /^trunc_f32 :: proc (val: f32) -> f32 #intrinsic ---$/ @@ -919,15 +929,19 @@ trunc_f64 /usr/share/onyx/core/intrinsics.onyx /^trunc_f64 :: proc (val: f64) ttf src/main.onyx /^ttf : TrueTypeFont$/ ttf_create src/font.onyx /^ttf_create :: proc (ttf_data: [] u8) -> TrueTypeFont {$/ ttf_glyph_count src/font.onyx /^ttf_glyph_count :: proc (use ttf: ^TrueTypeFont) -> u32 {$/ +ttf_glyph_destroy src/font.onyx /^ttf_glyph_destroy :: proc (glyph: ^TTGlyph) {$/ ttf_lookup_glyph_by_char src/font.onyx /^ttf_lookup_glyph_by_char :: proc (use ttf: ^TrueTypeFont, charcode: u32) -> u32 {$/ ttf_lookup_glyph_offset src/font.onyx /^ttf_lookup_glyph_offset :: proc (use ttf: ^TrueTypeFont, glyph_index: i32) -> u32 {$/ +ttf_lookup_horizontal_metrics src/font.onyx /^ttf_lookup_horizontal_metrics :: proc (use ttf: ^TrueTypeFont, glyph_index: u32) -> TTHorizontalMetrics {$/ ttf_read_cmap src/font.onyx /^ttf_read_cmap :: proc (use ttf: ^TrueTypeFont, offset: u32) {$/ ttf_read_cmap0 src/font.onyx /^ttf_read_cmap0 :: proc (use ttf: ^TrueTypeFont) {$/ ttf_read_cmap4 src/font.onyx /^ttf_read_cmap4 :: proc (use ttf: ^TrueTypeFont) {$/ ttf_read_cmap_table src/font.onyx /^ttf_read_cmap_table :: proc (use ttf: ^TrueTypeFont) {$/ ttf_read_glyph src/font.onyx /^ttf_read_glyph :: proc (use ttf: ^TrueTypeFont, glyph_index: i32) -> ^TTGlyph {$/ ttf_read_head_table src/font.onyx /^ttf_read_head_table :: proc (use ttf: ^TrueTypeFont) {$/ +ttf_read_hhea_table src/font.onyx /^ttf_read_hhea_table :: proc (use ttf: ^TrueTypeFont) {$/ ttf_read_offset_table src/font.onyx /^ttf_read_offset_table :: proc (use ttf: ^TrueTypeFont) {$/ +ttf_render_glyph src/font.onyx /^ttf_render_glyph :: proc (use ttf: ^TrueTypeFont, glyph: ^TTGlyph, data: ^u8, width: u32, height: u32) {$/ uniform1f /usr/share/onyx/core/js/webgl.onyx /^uniform1f :: proc (loc: GLUniformLocation, x: GLfloat) #foreign "gl" "uniform1f" ---$/ uniform1i /usr/share/onyx/core/js/webgl.onyx /^uniform1i :: proc (loc: GLUniformLocation, x: GLint) #foreign "gl" "uniform1i" ---$/ uniform2f /usr/share/onyx/core/js/webgl.onyx /^uniform2f :: proc (loc: GLUniformLocation, x: GLfloat, y: GLfloat) #foreign "gl" "uniform2f" ---$/ @@ -942,7 +956,11 @@ uniformMatrix4 /usr/share/onyx/core/js/webgl.onyx /^uniformMatrix4 update src/main.onyx /^update :: proc () {$/ useProgram /usr/share/onyx/core/js/webgl.onyx /^useProgram :: proc (program: GLProgram) #foreign "gl" "useProgram" ---$/ v2_add src/vecmath.onyx /^v2_add :: proc (a: V2($T), b: V2(T)) -> V2(T) {$/ +v2_lerp src/vecmath.onyx /^v2_lerp :: proc (t: f32, start: V2($T), end: V2(T)) -> V2(T) {$/ v2_mul src/vecmath.onyx /^v2_mul :: proc (a: V2($T), scalar: T) -> V2(T) {$/ +v2_on_segment src/vecmath.onyx /^v2_on_segment :: proc (a: V2($T), b: V2(T), c: V2(T)) -> bool {$/ +v2_orientation src/vecmath.onyx /^v2_orientation :: proc (a: V2($T), b: V2(T), c: V2(T)) -> i32 {$/ +v2_square_dist src/vecmath.onyx /^v2_square_dist :: proc (a: V2($T), b: V2(T)) -> T {$/ v2_sub src/vecmath.onyx /^v2_sub :: proc (a: V2($T), b: V2(T)) -> V2(T) {$/ validateProgram /usr/share/onyx/core/js/webgl.onyx /^validateProgram :: proc (program: GLProgram) #foreign "gl" "validateProgram" ---$/ vertexAttrib1f /usr/share/onyx/core/js/webgl.onyx /^vertexAttrib1f :: proc (idx: GLuint, x: GLfloat) #foreign "gl" "vertexAttrib1f" ---$/