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