From dd34e653988f1390b9adc507586707e32ff292ab Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Sat, 30 May 2020 12:52:23 +0200 Subject: [PATCH] gg: sokol fixes and text rendering benchmark --- Makefile | 6 +- examples/gg/gg2.v | 14 +-- examples/gg/gg_freetype.v | 61 +++++++++++- examples/sokol/freetype_raven.v | 160 ++++++++++++++++++++++++++++++++ vlib/gg2/gg.v | 20 ++-- 5 files changed, 241 insertions(+), 20 deletions(-) create mode 100644 examples/sokol/freetype_raven.v diff --git a/Makefile b/Makefile index c9c9339b5c..7a3f8295b0 100644 --- a/Makefile +++ b/Makefile @@ -63,10 +63,10 @@ endif @echo "V has been successfully built" @./v -version -clean: clean_tmp - git clean -xf +#clean: clean_tmp +#git clean -xf -clean_tmp: +clean: rm -rf $(TMPTCC) rm -rf $(TMPVC) diff --git a/examples/gg/gg2.v b/examples/gg/gg2.v index 8dda5b9616..637ab6976c 100644 --- a/examples/gg/gg2.v +++ b/examples/gg/gg2.v @@ -16,7 +16,7 @@ mut: fn main() { mut app := &App{} - app.gg = gg.new_context({ + app.gg = gg.new_context( bg_color: gx.white width: win_width height: win_height @@ -25,8 +25,8 @@ fn main() { window_title: 'Empty window' frame_fn: frame user_data: app - font_path: os.resource_abs_path('assets/fonts/RobotoMono-Regular.ttf') - }) + //font_path: os.resource_abs_path('assets/fonts/RobotoMono-Regular.ttf') + ) app.gg.run() } @@ -34,17 +34,19 @@ fn frame(user_data voidptr) { mut app := &App(user_data) mut gg := app.gg gg.begin() + /* if gg.fons == 0 { gg.init_font() } + */ app.draw() - C.sfons_flush(gg.fons) + //C.sfons_flush(gg.fons) gg.end() } fn (app &App) draw() { - app.gg.draw_text_def(200,20, 'hello world!') - app.gg.draw_text_def(300,300, 'привет') + //app.gg.draw_text_def(200,20, 'hello world!') + //app.gg.draw_text_def(300,300, 'привет') app.gg.draw_rect(10, 10, 100, 30, gx.blue) app.gg.draw_empty_rect(10, 150, 80, 40, gx.green) } diff --git a/examples/gg/gg_freetype.v b/examples/gg/gg_freetype.v index 3e50d0aee1..78e54302df 100644 --- a/examples/gg/gg_freetype.v +++ b/examples/gg/gg_freetype.v @@ -4,13 +4,61 @@ import gg import freetype import gx import glfw +import time const ( win_width = 600 - win_height = 300 + win_height = 700 bg_color = gx.white ) +const ( +text = ' +Once upon a midnight dreary, while I pondered, weak and weary, +Over many a quaint and curious volume of forgotten lore— + While I nodded, nearly napping, suddenly there came a tapping, +As of some one gently rapping, rapping at my chamber door. +“’Tis some visitor,” I muttered, “tapping at my chamber door— + Only this and nothing more.” + + Ah, distinctly I remember it was in the bleak December; +And each separate dying ember wrought its ghost upon the floor. + Eagerly I wished the morrow;—vainly I had sought to borrow + From my books surcease of sorrow—sorrow for the lost Lenore— +For the rare and radiant maiden whom the angels name Lenore— + Nameless here for evermore. + + And the silken, sad, uncertain rustling of each purple curtain +Thrilled me—filled me with fantastic terrors never felt before; + So that now, to still the beating of my heart, I stood repeating + “’Tis some visitor entreating entrance at my chamber door— +Some late visitor entreating entrance at my chamber door;— + This it is and nothing more.” + + Presently my soul grew stronger; hesitating then no longer, +“Sir,” said I, “or Madam, truly your forgiveness I implore; + But the fact is I was napping, and so gently you came rapping, + And so faintly you came tapping, tapping at my chamber door, +That I scarce was sure I heard you”—here I opened wide the door;— + Darkness there and nothing more. + +Deep into that darkness peering, long I stood there wondering, fearing, +Doubting, dreaming dreams no mortal ever dared to dream before; + But the silence was unbroken, and the stillness gave no token, + And the only word there spoken was the whispered word, “Lenore?” +This I whispered, and an echo murmured back the word, “Lenore!”— + Merely this and nothing more. + + Back into the chamber turning, all my soul within me burning, +Soon again I heard a tapping somewhat louder than before. + “Surely,” said I, “surely that is something at my window lattice; + Let me see, then, what thereat is, and this mystery explore— +Let my heart be still a moment and this mystery explore;— + ’Tis the wind and nothing more!” +' +lines = text.split('\n') +) + struct Context { mut: @@ -27,7 +75,7 @@ fn main() { use_ortho: true // This is needed for 2D drawing create_window: true window_title: 'Empty window' - window_user_ptr: ctx + //window_user_ptr: ctx }) } ctx.gg.window.set_user_ptr(ctx) // TODO remove this when `window_user_ptr:` works @@ -37,13 +85,15 @@ fn main() { width: win_width height: win_height use_ortho: true - font_size: 18 + font_size: 13 scale: 2 }) for { + t := time.ticks() gg.clear(bg_color) ctx.draw() ctx.gg.render() + println(time.ticks()-t) if ctx.gg.window.should_close() { ctx.gg.window.destroy() return @@ -52,5 +102,10 @@ fn main() { } fn (ctx Context) draw() { + mut y := 10 + for line in lines { + ctx.ft.draw_text_def(10,y, line) + y += 15 + } } diff --git a/examples/sokol/freetype_raven.v b/examples/sokol/freetype_raven.v new file mode 100644 index 0000000000..1d52d3fd44 --- /dev/null +++ b/examples/sokol/freetype_raven.v @@ -0,0 +1,160 @@ +import sokol +import sokol.sapp +import sokol.gfx +import sokol.sgl +import sokol.sfons +import os +import time + + +const ( +text = ' +Once upon a midnight dreary, while I pondered, weak and weary, +Over many a quaint and curious volume of forgotten lore— + While I nodded, nearly napping, suddenly there came a tapping, +As of some one gently rapping, rapping at my chamber door. +“’Tis some visitor,” I muttered, “tapping at my chamber door— + Only this and nothing more.” + + Ah, distinctly I remember it was in the bleak December; +And each separate dying ember wrought its ghost upon the floor. + Eagerly I wished the morrow;—vainly I had sought to borrow + From my books surcease of sorrow—sorrow for the lost Lenore— +For the rare and radiant maiden whom the angels name Lenore— + Nameless here for evermore. + + And the silken, sad, uncertain rustling of each purple curtain +Thrilled me—filled me with fantastic terrors never felt before; + So that now, to still the beating of my heart, I stood repeating + “’Tis some visitor entreating entrance at my chamber door— +Some late visitor entreating entrance at my chamber door;— + This it is and nothing more.” + + Presently my soul grew stronger; hesitating then no longer, +“Sir,” said I, “or Madam, truly your forgiveness I implore; + But the fact is I was napping, and so gently you came rapping, + And so faintly you came tapping, tapping at my chamber door, +That I scarce was sure I heard you”—here I opened wide the door;— + Darkness there and nothing more. + +Deep into that darkness peering, long I stood there wondering, fearing, +Doubting, dreaming dreams no mortal ever dared to dream before; + But the silence was unbroken, and the stillness gave no token, + And the only word there spoken was the whispered word, “Lenore?” +This I whispered, and an echo murmured back the word, “Lenore!”— + Merely this and nothing more. + + Back into the chamber turning, all my soul within me burning, +Soon again I heard a tapping somewhat louder than before. + “Surely,” said I, “surely that is something at my window lattice; + Let me see, then, what thereat is, and this mystery explore— +Let my heart be still a moment and this mystery explore;— + ’Tis the wind and nothing more!” +' +lines = text.split('\n') +) + +struct AppState { +mut: + pass_action C.sg_pass_action + fons &C.FONScontext + font_normal int + inited bool +} + +fn main() { + mut color_action := C.sg_color_attachment_action{ + action: C.SG_ACTION_CLEAR + } + color_action.val[0] = 1 + color_action.val[1] = 1 + color_action.val[2] = 1 + color_action.val[3] = 1.0 + mut pass_action := C.sg_pass_action{} + pass_action.colors[0] = color_action + state := &AppState{ + pass_action: pass_action + fons: &C.FONScontext(0) + } + title := 'V Metal/GL Text Rendering' + desc := C.sapp_desc{ + user_data: state + init_userdata_cb: init + frame_userdata_cb: frame + window_title: title.str + html5_canvas_name: title.str + width: 600 + height: 700 + high_dpi: true + } + sapp.run(&desc) +} + +fn init(user_data voidptr) { + mut state := &AppState(user_data) + // dont actually alocate this on the heap in real life + gfx.setup(&C.sg_desc{ + mtl_device: sapp.metal_get_device() + mtl_renderpass_descriptor_cb: sapp.metal_get_renderpass_descriptor + mtl_drawable_cb: sapp.metal_get_drawable + d3d11_device: sapp.d3d11_get_device() + d3d11_device_context: sapp.d3d11_get_device_context() + d3d11_render_target_view_cb: sapp.d3d11_get_render_target_view + d3d11_depth_stencil_view_cb: sapp.d3d11_get_depth_stencil_view + }) + s := &C.sgl_desc_t{} + C.sgl_setup(s) + state.fons = sfons.create(512, 512, 1) + // or use DroidSerif-Regular.ttf + if bytes := os.read_bytes(os.resource_abs_path('../assets/fonts/RobotoMono-Regular.ttf')) { + println('loaded font: $bytes.len') + state.font_normal = C.fonsAddFontMem(state.fons, 'sans', bytes.data, bytes.len, false) + } +} + +fn frame(user_data voidptr) { + t := time.ticks() + mut state := &AppState(user_data) + state.render_font() + gfx.begin_default_pass(&state.pass_action, sapp.width(), sapp.height()) + sgl.draw() + gfx.end_pass() + gfx.commit() + println(time.ticks()-t) +} + +const ( + +black = C.sfons_rgba(0, 0, 0, 255) +) + +fn (state &AppState) render_font() { + lh := 30 + mut dy := lh + if !state.inited { + state.fons.clear_state() + sgl.defaults() + sgl.matrix_mode_projection() + sgl.ortho(0.0, f32(C.sapp_width()), f32(C.sapp_height()), 0.0, -1.0, 1.0) + state.fons.set_font(state.font_normal) + state.fons.set_size(100.0) + C.fonsSetColor(state.fons, black) + C.fonsSetFont(state.fons, state.font_normal) + C.fonsSetSize(state.fons, 35.0) + state.inited = true + } + + for line in lines { + C.fonsDrawText(state.fons, 40, dy, line.str, C.NULL) + dy += lh + } + C.sfons_flush(state.fons) +} + +fn line(sx f32, sy f32, ex f32, ey f32) { + sgl.begin_lines() + sgl.c4b(255, 255, 0, 128) + sgl.v2f(sx, sy) + sgl.v2f(ex, ey) + sgl.end() +} diff --git a/vlib/gg2/gg.v b/vlib/gg2/gg.v index f0656e7da7..88d7767dd2 100644 --- a/vlib/gg2/gg.v +++ b/vlib/gg2/gg.v @@ -49,12 +49,14 @@ pub mut: } // TODO remove globals +/* __global g_fons &C.FONScontext __global g_font_normal int __global g_font_path string +*/ -fn init_sokol_window() { - desc := sg_desc{ +fn init_sokol_window(user_data voidptr) { + desc := C.sg_desc{ mtl_device: sapp.metal_get_device() mtl_renderpass_descriptor_cb: sapp.metal_get_renderpass_descriptor mtl_drawable_cb: sapp.metal_get_drawable @@ -64,8 +66,9 @@ fn init_sokol_window() { d3d11_depth_stencil_view_cb: sapp.d3d11_get_depth_stencil_view } gfx.setup(&desc) - sgl_desc := sgl_desc_t{} + sgl_desc := C.sgl_desc_t{} sgl.setup(&sgl_desc) + /* g_fons = sfons.create(512, 512, 1) if g_font_path.len == 0 || !os.exists(g_font_path) { println('failed to load font "$g_font_path"') @@ -76,11 +79,12 @@ fn init_sokol_window() { return } g_font_normal = C.fonsAddFontMem(g_fons, 'sans', bytes.data, bytes.len, false) + */ } pub fn new_context(cfg Config) &GG { //C.printf('new_context() %p\n', cfg.user_data) - window := sapp_desc{ + window := C.sapp_desc{ user_data: cfg.user_data init_userdata_cb: init_sokol_window frame_userdata_cb: cfg.frame_fn @@ -90,14 +94,14 @@ pub fn new_context(cfg Config) &GG { height: cfg.height high_dpi: true } - g_font_path = cfg.font_path + //g_font_path = cfg.font_path if cfg.use_ortho {} else {} return &GG{ width: cfg.width 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) + clear_pass: gfx.create_clear_pass(0,0,0,0) //f64(cfg.bg_color.r) / 255.0, f64(cfg.bg_color.g) / 255.0, f64(cfg.bg_color.b) / 255.0, 1.0) scale: 1 // scale fons:0 } @@ -126,8 +130,8 @@ pub fn (ctx &GG) draw_text_def(x, y int, text string) { pub fn (mut gg GG) init_font() { // TODO - gg.fons =g_fons - gg.font_normal=g_font_normal + ////gg.fons =g_fons + //gg.font_normal=g_font_normal } pub fn (gg &GG) run() {