tetris: restore text rendering with gg2.ft.draw_text

pull/5204/head
Delyan Angelov 2020-06-03 23:08:55 +03:00
parent e91642e615
commit 576e80b3a9
3 changed files with 84 additions and 55 deletions

View File

@ -4,10 +4,12 @@
module main module main
import os
import rand import rand
import time import time
import gx import gx
import gg2 as gg import gg2 as gg
import gg2.ft
import sokol.sapp import sokol.sapp
const ( const (
@ -124,10 +126,9 @@ struct Game {
// Index of the rotation (0-3) // Index of the rotation (0-3)
rotation_idx int rotation_idx int
// gg context for drawing // gg context for drawing
gg &gg.GG gg &gg.GG = voidptr(0)
// ft context for font drawing // ft context for font drawing
//ft &freetype.FreeType ft &ft.FT = voidptr(0)
//ft &ft.FT
font_loaded bool font_loaded bool
// frame/time counters: // frame/time counters:
frame int frame int
@ -136,6 +137,13 @@ struct Game {
second_sw time.StopWatch = time.new_stopwatch({}) second_sw time.StopWatch = time.new_stopwatch({})
} }
const ( fpath = os.resource_abs_path('../assets/fonts/RobotoMono-Regular.ttf') )
fn init_gui(mut game Game){
x := ft.new({ font_path: fpath }) or {panic(err)}
game.ft = x
game.font_loaded = true
}
[if showfps] [if showfps]
fn (game &Game) showfps() { fn (game &Game) showfps() {
game.frame++ game.frame++
@ -151,27 +159,18 @@ fn (game &Game) showfps() {
fn frame(game &Game) { fn frame(game &Game) {
game.frame_sw.restart() game.frame_sw.restart()
//C.sfons_flush(game.ft.fons) game.ft.flush()
game.gg.begin() game.gg.begin()
game.draw_scene() game.draw_scene()
game.showfps() game.showfps()
game.gg.end() game.gg.end()
} }
fn main() { fn main() {
// TODO
/*
f := ft.new(
//font_path: os.resource_abs_path('../assets/fonts/RobotoMono-Regular.ttf')
font_path: ('../assets/fonts/RobotoMono-Regular.ttf')
) or {
println('failed to loat the font')
return
}
*/
mut game := &Game{ mut game := &Game{
gg: 0 gg: 0
//ft: f ft: 0
} }
game.gg = gg.new_context( game.gg = gg.new_context(
bg_color: gx.white bg_color: gx.white
@ -180,9 +179,10 @@ fn main() {
use_ortho: true // This is needed for 2D drawing use_ortho: true // This is needed for 2D drawing
create_window: true create_window: true
window_title: 'V Tetris' window_title: 'V Tetris'
frame_fn: frame //
user_data: game user_data: game
//on_key_down: key_down init_fn: init_gui
frame_fn: frame
event_cb: on_event event_cb: on_event
) )
game.init_game() game.init_game()
@ -352,17 +352,17 @@ fn (g &Game) draw_field() {
fn (mut g Game) draw_ui() { fn (mut g Game) draw_ui() {
if g.font_loaded { if g.font_loaded {
//g.ft.draw_text(1, 3, g.score.str(), text_cfg) g.ft.draw_text(1, 3, g.score.str(), text_cfg)
if g.state == .gameover { if g.state == .gameover {
g.gg.draw_rect(0, win_height / 2 - text_size, win_width, g.gg.draw_rect(0, win_height / 2 - text_size, win_width,
5 * text_size, ui_color) 5 * text_size, ui_color)
//g.ft.draw_text(1, win_height / 2 + 0 * text_size, 'Game Over', over_cfg) g.ft.draw_text(1, win_height / 2 + 0 * text_size, 'Game Over', over_cfg)
//g.ft.draw_text(1, win_height / 2 + 2 * text_size, 'Space to restart', over_cfg) g.ft.draw_text(1, win_height / 2 + 2 * text_size, 'Space to restart', over_cfg)
} else if g.state == .paused { } else if g.state == .paused {
g.gg.draw_rect(0, win_height / 2 - text_size, win_width, g.gg.draw_rect(0, win_height / 2 - text_size, win_width,
5 * text_size, ui_color) 5 * text_size, ui_color)
//g.ft.draw_text(1, win_height / 2 + 0 * text_size, 'Game Paused', text_cfg) g.ft.draw_text(1, win_height / 2 + 0 * text_size, 'Game Paused', text_cfg)
//g.ft.draw_text(1, win_height / 2 + 2 * text_size, 'SPACE to resume', text_cfg) g.ft.draw_text(1, win_height / 2 + 2 * text_size, 'SPACE to resume', text_cfg)
} }
} }
//g.gg.draw_rect(0, block_size, win_width, limit_thickness, ui_color) //g.gg.draw_rect(0, block_size, win_width, limit_thickness, ui_color)

View File

@ -34,9 +34,7 @@ pub fn new(c Config) ?&FT{
println('failed to load font "$c.font_path"') println('failed to load font "$c.font_path"')
return none return none
} }
s := &C.sgl_desc_t{} fons := sfons.create(512, 512, 1)
C.sgl_setup(s)
fons :=sfons.create(512, 512, 1)
return &FT{ return &FT{
fons : fons fons : fons
font_normal: C.fonsAddFontMem(fons, 'sans', bytes.data, bytes.len, false) font_normal: C.fonsAddFontMem(fons, 'sans', bytes.data, bytes.len, false)
@ -44,27 +42,26 @@ pub fn new(c Config) ?&FT{
} }
pub fn (gg &FT) draw_text(x, y int, text string, cfg gx.TextCfg) { pub fn (ft &FT) draw_text(x, y int, text string, cfg gx.TextCfg) {
/* ft.fons.set_font(ft.font_normal)
gg.fons.set_font(gg.font_normal) ft.fons.set_size(2*f32(cfg.size)) // TODO: is this 2* needed?
gg.fons.set_size(f32(cfg.size)) C.fonsSetAlign(ft.fons, C.FONS_ALIGN_LEFT | C.FONS_ALIGN_TOP)
color := C.sfons_rgba(cfg.color.r, cfg.color.g, cfg.color.b, 255)
C.fonsSetColor(ft.fons, color)
ascender := f32(0.0) ascender := f32(0.0)
descender := f32(0.0) descender := f32(0.0)
lh := f32(0.0) lh := f32(0.0)
gg.fons.vert_metrics(&ascender, &descender, &lh) ft.fons.vert_metrics(&ascender, &descender, &lh)
color:= C.sfons_rgba(cfg.color.r, cfg.color.g, cfg.color.b, 255) C.fonsDrawText(ft.fons, x, y, text.str, 0) // TODO: check offsets/alignment
C.fonsSetColor(gg.fons, color)
C.fonsDrawText(gg.fons, x, y, text.str, 0)
*/
} }
pub fn (ctx &FT) draw_text_def(x, y int, text string) { pub fn (ft &FT) draw_text_def(x, y int, text string) {
cfg := gx.TextCfg { cfg := gx.TextCfg {
color: gx.black color: gx.black
size: default_font_size size: default_font_size
align: gx.align_left align: gx.align_left
} }
ctx.draw_text(x, y, text, cfg) ft.draw_text(x, y, text, cfg)
} }
pub fn (mut gg FT) init_font() { pub fn (mut gg FT) init_font() {
@ -73,4 +70,6 @@ pub fn (mut gg FT) init_font() {
//gg.font_normal=g_font_normal //gg.font_normal=g_font_normal
} }
pub fn (ft &FT) flush(){
sfons.flush(ft.fons)
}

View File

@ -10,6 +10,9 @@ import sokol.sapp
import sokol.sgl import sokol.sgl
import sokol.gfx import sokol.gfx
type FNvoidptr1 fn(voidptr)
type FNvoidptr2 fn(voidptr,voidptr)
pub struct Config { pub struct Config {
pub: pub:
width int width int
@ -24,10 +27,12 @@ pub:
window_title string window_title string
always_on_top bool always_on_top bool
scale int scale int
frame_fn fn(voidptr)
bg_color gx.Color bg_color gx.Color
on_key_down fn(voidptr) init_fn FNvoidptr1 = voidptr(0)
event_cb fn(voidptr, voidptr) frame_fn FNvoidptr1 = voidptr(0)
on_key_down FNvoidptr1 = voidptr(0)
event_cb FNvoidptr2 = voidptr(0)
wait_events bool = false // set this to true for UIs, to save power
} }
pub struct GG { pub struct GG {
@ -37,10 +42,11 @@ pub mut:
height int height int
clear_pass C.sg_pass_action clear_pass C.sg_pass_action
window C.sapp_desc window C.sapp_desc
render_fn fn() config Config
} }
fn init_sokol_window(user_data voidptr) { fn gg_init_sokol_window(user_data voidptr) {
mut g := &GG(user_data)
desc := C.sg_desc{ desc := C.sg_desc{
mtl_device: sapp.metal_get_device() mtl_device: sapp.metal_get_device()
mtl_renderpass_descriptor_cb: sapp.metal_get_renderpass_descriptor mtl_renderpass_descriptor_cb: sapp.metal_get_renderpass_descriptor
@ -53,19 +59,47 @@ fn init_sokol_window(user_data voidptr) {
gfx.setup(&desc) gfx.setup(&desc)
sgl_desc := C.sgl_desc_t{} sgl_desc := C.sgl_desc_t{}
sgl.setup(&sgl_desc) sgl.setup(&sgl_desc)
if g.config.init_fn != voidptr(0) {
g.config.init_fn( g.config.user_data )
}
} }
fn gg_frame_fn(user_data voidptr) {
mut g := &GG(user_data)
if g.config.frame_fn != voidptr(0) {
g.config.frame_fn( g.config.user_data )
}
}
fn gg_event_cb(e &C.sapp_event, b voidptr){
mut g := &GG(b)
if g.config.event_cb != voidptr(0) {
g.config.event_cb(e, g.config.user_data)
}
}
//
fn eventcb(e &C.sapp_event, b voidptr){ fn eventcb(e &C.sapp_event, b voidptr){
println("EVENT") println("EVENT")
} }
pub fn new_context(cfg Config) &GG { pub fn new_context(cfg Config) &GG {
mut g := &GG{
width: cfg.width
height: cfg.height
clear_pass: gfx.create_clear_pass( f32(cfg.bg_color.r) / 255.0, f32(cfg.bg_color.g) / 255.0,
f32(cfg.bg_color.b) / 255.0, 1.0)
scale: 1 // scale
config: cfg
}
//C.printf('new_context() %p\n', cfg.user_data) //C.printf('new_context() %p\n', cfg.user_data)
window := C.sapp_desc{ window := C.sapp_desc{
user_data: cfg.user_data user_data: g
init_userdata_cb: init_sokol_window init_userdata_cb: gg_init_sokol_window
frame_userdata_cb: cfg.frame_fn frame_userdata_cb: gg_frame_fn
event_userdata_cb: cfg.event_cb //eventcb event_userdata_cb: gg_event_cb //eventcb
window_title: cfg.window_title.str window_title: cfg.window_title.str
html5_canvas_name: cfg.window_title.str html5_canvas_name: cfg.window_title.str
width: cfg.width width: cfg.width
@ -74,14 +108,8 @@ pub fn new_context(cfg Config) &GG {
} }
if cfg.use_ortho {} if cfg.use_ortho {}
else {} else {}
return &GG{ g.window = window
width: cfg.width return g
height: cfg.height
window: window
clear_pass: gfx.create_clear_pass( f32(cfg.bg_color.r) / 255.0, f32(cfg.bg_color.g) / 255.0,
f32(cfg.bg_color.b) / 255.0, 1.0)
scale: 1 // scale
}
} }
pub fn (gg &GG) run() { pub fn (gg &GG) run() {
@ -148,7 +176,9 @@ pub fn (gg &GG) end() {
sgl.draw() sgl.draw()
gfx.end_pass() gfx.end_pass()
gfx.commit() gfx.commit()
if gg.config.wait_events {
wait_events() wait_events()
}
} }
pub fn (ctx &GG) draw_line(x, y, x2, y2 f32, color gx.Color) {} pub fn (ctx &GG) draw_line(x, y, x2, y2 f32, color gx.Color) {}