1 /*
2 * Copyright 2013 Jeremie Roy. All rights reserved.
3 * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
4 */
5
6 #include "common.h"
7 #include "bgfx_utils.h"
8
9 #include <bx/timer.h>
10 #include <bx/string.h>
11 #include <bx/math.h>
12
13 #include "font/font_manager.h"
14 #include "font/text_buffer_manager.h"
15 #include "entry/input.h"
16
17 #include <iconfontheaders/icons_font_awesome.h>
18 #include <iconfontheaders/icons_kenney.h>
19
20 #include <wchar.h>
21
22 #include "imgui/imgui.h"
23
24 namespace
25 {
26
loadTtf(FontManager * _fm,const char * _filePath)27 TrueTypeHandle loadTtf(FontManager* _fm, const char* _filePath)
28 {
29 uint32_t size;
30 void* data = load(_filePath, &size);
31
32 if (NULL != data)
33 {
34 TrueTypeHandle handle = _fm->createTtf( (uint8_t*)data, size);
35 BX_FREE(entry::getAllocator(), data);
36 return handle;
37 }
38
39 TrueTypeHandle invalid = BGFX_INVALID_HANDLE;
40 return invalid;
41 }
42
43 static const char* s_fontFilePath[] =
44 {
45 "font/droidsans.ttf",
46 "font/chp-fire.ttf",
47 "font/bleeding_cowboys.ttf",
48 "font/mias_scribblings.ttf",
49 "font/ruritania.ttf",
50 "font/signika-regular.ttf",
51 "font/five_minutes.otf",
52 };
53
54 class ExampleFont : public entry::AppI
55 {
56 public:
ExampleFont(const char * _name,const char * _description,const char * _url)57 ExampleFont(const char* _name, const char* _description, const char* _url)
58 : entry::AppI(_name, _description, _url)
59 {
60 }
61
init(int32_t _argc,const char * const * _argv,uint32_t _width,uint32_t _height)62 void init(int32_t _argc, const char* const* _argv, uint32_t _width, uint32_t _height) override
63 {
64 Args args(_argc, _argv);
65
66 m_width = _width;
67 m_height = _height;
68 m_debug = BGFX_DEBUG_NONE;
69 m_reset = BGFX_RESET_VSYNC;
70
71 bgfx::Init init;
72 init.type = args.m_type;
73 init.vendorId = args.m_pciId;
74 init.resolution.width = m_width;
75 init.resolution.height = m_height;
76 init.resolution.reset = m_reset;
77 bgfx::init(init);
78
79 // Enable debug text.
80 bgfx::setDebug(m_debug);
81
82 // Set view 0 clear state.
83 bgfx::setViewClear(0
84 , BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH
85 , 0x303030ff
86 , 1.0f
87 , 0
88 );
89
90 // Init the text rendering system.
91 m_fontManager = new FontManager(512);
92 m_textBufferManager = new TextBufferManager(m_fontManager);
93
94 // Load some TTF files.
95 for (uint32_t ii = 0; ii < numFonts; ++ii)
96 {
97 // Instantiate a usable font.
98 m_fontFiles[ii] = loadTtf(m_fontManager, s_fontFilePath[ii]);
99 m_fonts[ii] = m_fontManager->createFontByPixelSize(m_fontFiles[ii], 0, 32);
100
101 // Preload glyphs and blit them to atlas.
102 m_fontManager->preloadGlyph(m_fonts[ii], L"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ. \n");
103
104 // You can unload the truetype files at this stage, but in that
105 // case, the set of glyph's will be limited to the set of preloaded
106 // glyph.
107 m_fontManager->destroyTtf(m_fontFiles[ii]);
108 }
109
110 m_fontAwesomeTtf = loadTtf(m_fontManager, "font/fontawesome-webfont.ttf");
111 m_fontKenneyTtf = loadTtf(m_fontManager, "font/kenney-icon-font.ttf");
112
113 // This font doesn't have any preloaded glyph's but the truetype file
114 // is loaded so glyph will be generated as needed.
115 m_fontAwesome72 = m_fontManager->createFontByPixelSize(m_fontAwesomeTtf, 0, 72);
116 m_fontKenney64 = m_fontManager->createFontByPixelSize(m_fontKenneyTtf, 0, 64);
117
118 m_visitorTtf = loadTtf(m_fontManager, "font/visitor1.ttf");
119
120 // This font doesn't have any preloaded glyph's but the truetype file
121 // is loaded so glyph will be generated as needed.
122 m_visitor10 = m_fontManager->createFontByPixelSize(m_visitorTtf, 0, 10);
123
124 //create a static text buffer compatible with alpha font
125 //a static text buffer content cannot be modified after its first submit.
126 m_staticText = m_textBufferManager->createTextBuffer(FONT_TYPE_ALPHA, BufferType::Static);
127
128 // The pen position represent the top left of the box of the first line
129 // of text.
130 m_textBufferManager->setPenPosition(m_staticText, 24.0f, 100.0f);
131
132 for (uint32_t ii = 0; ii < numFonts; ++ii)
133 {
134 // Add some text to the buffer.
135 // The position of the pen is adjusted when there is an endline.
136 m_textBufferManager->appendText(m_staticText, m_fonts[ii], L"The quick brown fox jumps over the lazy dog\n");
137 }
138
139 // Now write some styled text.
140
141 // Setup style colors.
142 m_textBufferManager->setBackgroundColor(m_staticText, 0x551111ff);
143 m_textBufferManager->setUnderlineColor(m_staticText, 0xff2222ff);
144 m_textBufferManager->setOverlineColor(m_staticText, 0x2222ffff);
145 m_textBufferManager->setStrikeThroughColor(m_staticText, 0x22ff22ff);
146
147 // Background.
148 m_textBufferManager->setStyle(m_staticText, STYLE_BACKGROUND);
149 m_textBufferManager->appendText(m_staticText, m_fonts[0], L"The quick ");
150
151 // Strike-through.
152 m_textBufferManager->setStyle(m_staticText, STYLE_STRIKE_THROUGH);
153 m_textBufferManager->appendText(m_staticText, m_fonts[0], L"brown fox ");
154
155 // Overline.
156 m_textBufferManager->setStyle(m_staticText, STYLE_OVERLINE);
157 m_textBufferManager->appendText(m_staticText, m_fonts[0], L"jumps over ");
158
159 // Underline.
160 m_textBufferManager->setStyle(m_staticText, STYLE_UNDERLINE);
161 m_textBufferManager->appendText(m_staticText, m_fonts[0], L"the lazy ");
162
163 // Background + strike-through.
164 m_textBufferManager->setStyle(m_staticText, STYLE_BACKGROUND | STYLE_STRIKE_THROUGH);
165 m_textBufferManager->appendText(m_staticText, m_fonts[0], L"dog\n");
166
167 m_textBufferManager->setStyle(m_staticText, STYLE_NORMAL);
168 m_textBufferManager->appendText(m_staticText, m_fontAwesome72,
169 " " ICON_FA_POWER_OFF
170 " " ICON_FA_TWITTER_SQUARE
171 " " ICON_FA_CERTIFICATE
172 " " ICON_FA_FLOPPY_O
173 " " ICON_FA_GITHUB
174 " " ICON_FA_GITHUB_ALT
175 "\n"
176 );
177 m_textBufferManager->appendText(m_staticText, m_fontKenney64,
178 " " ICON_KI_COMPUTER
179 " " ICON_KI_JOYSTICK
180 " " ICON_KI_EXLAMATION
181 " " ICON_KI_STAR
182 " " ICON_KI_BUTTON_START
183 " " ICON_KI_DOWNLOAD
184 "\n"
185 );
186
187 // Create a transient buffer for real-time data.
188 m_transientText = m_textBufferManager->createTextBuffer(FONT_TYPE_ALPHA, BufferType::Transient);
189
190 imguiCreate();
191 }
192
shutdown()193 virtual int shutdown() override
194 {
195 imguiDestroy();
196
197 m_fontManager->destroyTtf(m_fontKenneyTtf);
198 m_fontManager->destroyTtf(m_fontAwesomeTtf);
199 m_fontManager->destroyTtf(m_visitorTtf);
200
201 // Destroy the fonts.
202 m_fontManager->destroyFont(m_fontKenney64);
203 m_fontManager->destroyFont(m_fontAwesome72);
204 m_fontManager->destroyFont(m_visitor10);
205 for (uint32_t ii = 0; ii < numFonts; ++ii)
206 {
207 m_fontManager->destroyFont(m_fonts[ii]);
208 }
209
210 m_textBufferManager->destroyTextBuffer(m_staticText);
211 m_textBufferManager->destroyTextBuffer(m_transientText);
212
213 delete m_textBufferManager;
214 delete m_fontManager;
215
216 // Shutdown bgfx.
217 bgfx::shutdown();
218
219 return 0;
220 }
221
update()222 bool update() override
223 {
224 if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState) )
225 {
226 imguiBeginFrame(m_mouseState.m_mx
227 , m_mouseState.m_my
228 , (m_mouseState.m_buttons[entry::MouseButton::Left ] ? IMGUI_MBUT_LEFT : 0)
229 | (m_mouseState.m_buttons[entry::MouseButton::Right ] ? IMGUI_MBUT_RIGHT : 0)
230 | (m_mouseState.m_buttons[entry::MouseButton::Middle] ? IMGUI_MBUT_MIDDLE : 0)
231 , m_mouseState.m_mz
232 , uint16_t(m_width)
233 , uint16_t(m_height)
234 );
235
236 showExampleDialog(this);
237
238 imguiEndFrame();
239
240 // This dummy draw call is here to make sure that view 0 is cleared
241 // if no other draw calls are submitted to view 0.
242 bgfx::touch(0);
243
244 int64_t now = bx::getHPCounter();
245 static int64_t last = now;
246 const int64_t frameTime = now - last;
247 last = now;
248 const double freq = double(bx::getHPFrequency() );
249 const double toMs = 1000.0 / freq;
250
251 // Use transient text to display debug information.
252 char fpsText[64];
253 bx::snprintf(fpsText, BX_COUNTOF(fpsText), "Frame: % 7.3f[ms]", double(frameTime) * toMs);
254
255 m_textBufferManager->clearTextBuffer(m_transientText);
256 m_textBufferManager->setPenPosition(m_transientText, m_width - 150.0f, 10.0f);
257 m_textBufferManager->appendText(m_transientText, m_visitor10, "Transient\n");
258 m_textBufferManager->appendText(m_transientText, m_visitor10, "text buffer\n");
259 m_textBufferManager->appendText(m_transientText, m_visitor10, fpsText);
260
261 const bx::Vec3 at = { 0.0f, 0.0f, 0.0f };
262 const bx::Vec3 eye = { 0.0f, 0.0f, -1.0f };
263
264 float view[16];
265 bx::mtxLookAt(view, eye, at);
266
267 const float centering = 0.5f;
268
269 // Setup a top-left ortho matrix for screen space drawing.
270 const bgfx::Caps* caps = bgfx::getCaps();
271 {
272 float ortho[16];
273 bx::mtxOrtho(
274 ortho
275 , centering
276 , m_width + centering
277 , m_height + centering
278 , centering
279 , 0.0f
280 , 100.0f
281 , 0.0f
282 , caps->homogeneousDepth
283 );
284 bgfx::setViewTransform(0, view, ortho);
285 bgfx::setViewRect(0, 0, 0, uint16_t(m_width), uint16_t(m_height) );
286 }
287
288 // Submit the debug text.
289 m_textBufferManager->submitTextBuffer(m_transientText, 0);
290
291 // Submit the static text.
292 m_textBufferManager->submitTextBuffer(m_staticText, 0);
293
294 // Advance to next frame. Rendering thread will be kicked to
295 // process submitted rendering primitives.
296 bgfx::frame();
297
298 return true;
299 }
300
301 return false;
302 }
303
304 entry::MouseState m_mouseState;
305
306 uint32_t m_width;
307 uint32_t m_height;
308 uint32_t m_debug;
309 uint32_t m_reset;
310
311 FontManager* m_fontManager;
312 TextBufferManager* m_textBufferManager;
313
314 FontHandle m_visitor10;
315 TrueTypeHandle m_fontAwesomeTtf;
316 TrueTypeHandle m_fontKenneyTtf;
317 FontHandle m_fontAwesome72;
318 FontHandle m_fontKenney64;
319 TrueTypeHandle m_visitorTtf;
320
321 TextBufferHandle m_transientText;
322 TextBufferHandle m_staticText;
323
324 static const uint32_t numFonts = BX_COUNTOF(s_fontFilePath);
325
326 TrueTypeHandle m_fontFiles[numFonts];
327 FontHandle m_fonts[numFonts];
328 };
329
330 } // namespace
331
332 ENTRY_IMPLEMENT_MAIN(
333 ExampleFont
334 , "10-font"
335 , "Use the font system to display text and styled text."
336 , "https://bkaradzic.github.io/bgfx/examples.html#font"
337 );
338