| 1 | import sokol.sapp |
| 2 | import sokol.gfx |
| 3 | import sokol.sgl |
| 4 | import fontstash |
| 5 | import sokol.sfons |
| 6 | import os |
| 7 | |
| 8 | const text = ' |
| 9 | Once upon a midnight dreary, while I pondered, weak and weary, |
| 10 | Over many a quaint and curious volume of forgotten lore— |
| 11 | While I nodded, nearly napping, suddenly there came a tapping, |
| 12 | As of some one gently rapping, rapping at my chamber door. |
| 13 | “’Tis some visitor,” I muttered, “tapping at my chamber door— |
| 14 | Only this and nothing more.” |
| 15 | |
| 16 | Ah, distinctly I remember it was in the bleak December; |
| 17 | And each separate dying ember wrought its ghost upon the floor. |
| 18 | Eagerly I wished the morrow;—vainly I had sought to borrow |
| 19 | From my books surcease of sorrow—sorrow for the lost Lenore— |
| 20 | For the rare and radiant maiden whom the angels name Lenore— |
| 21 | Nameless here for evermore. |
| 22 | |
| 23 | And the silken, sad, uncertain rustling of each purple curtain |
| 24 | Thrilled me—filled me with fantastic terrors never felt before; |
| 25 | So that now, to still the beating of my heart, I stood repeating |
| 26 | “’Tis some visitor entreating entrance at my chamber door— |
| 27 | Some late visitor entreating entrance at my chamber door;— |
| 28 | This it is and nothing more.” |
| 29 | |
| 30 | Presently my soul grew stronger; hesitating then no longer, |
| 31 | “Sir,” said I, “or Madam, truly your forgiveness I implore; |
| 32 | But the fact is I was napping, and so gently you came rapping, |
| 33 | And so faintly you came tapping, tapping at my chamber door, |
| 34 | That I scarce was sure I heard you”—here I opened wide the door;— |
| 35 | Darkness there and nothing more. |
| 36 | |
| 37 | Deep into that darkness peering, long I stood there wondering, fearing, |
| 38 | Doubting, dreaming dreams no mortal ever dared to dream before; |
| 39 | But the silence was unbroken, and the stillness gave no token, |
| 40 | And the only word there spoken was the whispered word, “Lenore?” |
| 41 | This I whispered, and an echo murmured back the word, “Lenore!”— |
| 42 | Merely this and nothing more. |
| 43 | |
| 44 | Back into the chamber turning, all my soul within me burning, |
| 45 | Soon again I heard a tapping somewhat louder than before. |
| 46 | “Surely,” said I, “surely that is something at my window lattice; |
| 47 | Let me see, then, what thereat is, and this mystery explore— |
| 48 | Let my heart be still a moment and this mystery explore;— |
| 49 | ’Tis the wind and nothing more!” |
| 50 | ' |
| 51 | |
| 52 | const lines = text.split('\n') |
| 53 | |
| 54 | struct AppState { |
| 55 | mut: |
| 56 | pass_action gfx.PassAction |
| 57 | fons &fontstash.Context = unsafe { nil } |
| 58 | font_normal int |
| 59 | inited bool |
| 60 | } |
| 61 | |
| 62 | fn main() { |
| 63 | mut color_action := gfx.ColorAttachmentAction{ |
| 64 | load_action: .clear |
| 65 | clear_value: gfx.Color{ |
| 66 | r: 1.0 |
| 67 | g: 1.0 |
| 68 | b: 1.0 |
| 69 | a: 1.0 |
| 70 | } |
| 71 | } |
| 72 | mut pass_action := gfx.PassAction{} |
| 73 | pass_action.colors[0] = color_action |
| 74 | state := &AppState{ |
| 75 | pass_action: pass_action |
| 76 | fons: unsafe { nil } // &fontstash.Context(0) |
| 77 | } |
| 78 | title := 'V Metal/GL Text Rendering' |
| 79 | desc := sapp.Desc{ |
| 80 | user_data: state |
| 81 | init_userdata_cb: init |
| 82 | frame_userdata_cb: frame |
| 83 | window_title: &char(title.str) |
| 84 | width: 600 |
| 85 | height: 700 |
| 86 | high_dpi: true |
| 87 | } |
| 88 | sapp.run(&desc) |
| 89 | } |
| 90 | |
| 91 | fn init(mut state AppState) { |
| 92 | desc := sapp.create_desc() |
| 93 | gfx.setup(&desc) |
| 94 | s := &sgl.Desc{} |
| 95 | sgl.setup(s) |
| 96 | state.fons = sfons.create(512, 512, 1) |
| 97 | // or use DroidSerif-Regular.ttf |
| 98 | if bytes := os.read_bytes(os.resource_abs_path(os.join_path('..', 'assets', 'fonts', |
| 99 | 'RobotoMono-Regular.ttf'))) |
| 100 | { |
| 101 | println('loaded font: ${bytes.len}') |
| 102 | state.font_normal = state.fons.add_font_mem('sans', bytes.clone(), true) |
| 103 | } |
| 104 | } |
| 105 | |
| 106 | fn frame(mut state AppState) { |
| 107 | state.render_font() |
| 108 | pass := sapp.create_default_pass(state.pass_action) |
| 109 | gfx.begin_pass(&pass) |
| 110 | sgl.draw() |
| 111 | gfx.end_pass() |
| 112 | gfx.commit() |
| 113 | } |
| 114 | |
| 115 | const black = sfons.rgba(0, 0, 0, 255) |
| 116 | |
| 117 | fn (mut state AppState) render_font() { |
| 118 | lh := 30 |
| 119 | mut dy := lh |
| 120 | mut fons := state.fons |
| 121 | if !state.inited { |
| 122 | fons.clear_state() |
| 123 | sgl.defaults() |
| 124 | sgl.matrix_mode_projection() |
| 125 | sgl.ortho(0.0, f32(sapp.width()), f32(sapp.height()), 0.0, -1.0, 1.0) |
| 126 | fons.set_font(state.font_normal) |
| 127 | fons.set_size(100.0) |
| 128 | fons.set_color(black) |
| 129 | fons.set_font(state.font_normal) |
| 130 | fons.set_size(35.0) |
| 131 | state.inited = true |
| 132 | } |
| 133 | |
| 134 | for line in lines { |
| 135 | fons.draw_text(40, dy, line) |
| 136 | dy += lh |
| 137 | } |
| 138 | sfons.flush(fons) |
| 139 | } |
| 140 | |