1
1
import imgui .ImFontAtlas ;
2
2
import imgui .ImFontConfig ;
3
3
import imgui .ImGui ;
4
+ import imgui .ImGuiFreeType ;
4
5
import imgui .ImGuiIO ;
5
6
import imgui .callbacks .ImStrConsumer ;
6
7
import imgui .callbacks .ImStrSupplier ;
29
30
30
31
@ SuppressWarnings ("MagicNumber" )
31
32
public final class ImGuiGlfwExample {
32
- private long windowPtr ; // current GLFW window pointer
33
+ private long windowPtr ; // pointer to the current GLFW window
33
34
34
- // To get window properties
35
+ // For application window properties
35
36
private final int [] winWidth = new int [1 ];
36
37
private final int [] winHeight = new int [1 ];
37
38
private final int [] fbWidth = new int [1 ];
@@ -48,7 +49,7 @@ public final class ImGuiGlfwExample {
48
49
private final ImGuiImplGl3 imGuiGl3 = new ImGuiImplGl3 ();
49
50
private String glslVersion = null ; // We can initialize our renderer with different versions of the GLSL
50
51
51
- // Ui to render
52
+ // User UI to render
52
53
private final ExampleUi exampleUi = new ExampleUi ();
53
54
54
55
public void run () throws Exception {
@@ -60,7 +61,7 @@ public void run() throws Exception {
60
61
destroyGlfw ();
61
62
}
62
63
63
- // Initialize GLFW + create OpenGL context.
64
+ // Initialize GLFW + create an OpenGL context.
64
65
// All code is mostly a copy-paste from the official LWJGL3 "Get Started": https://www.lwjgl.org/guide
65
66
private void initGlfw () {
66
67
// Setup an error callback. The default implementation
@@ -78,7 +79,6 @@ private void initGlfw() {
78
79
79
80
decideGlGlslVersions ();
80
81
81
- // Create the window
82
82
windowPtr = glfwCreateWindow (1280 , 768 , "Dear ImGui + GLFW + LWJGL Example" , NULL , NULL );
83
83
84
84
if (windowPtr == NULL ) {
@@ -134,6 +134,7 @@ private void initImGui() {
134
134
// This line is critical for Dear ImGui to work.
135
135
ImGui .createContext ();
136
136
137
+ // ------------------------------------------------------------
137
138
// Initialize ImGuiIO config
138
139
final ImGuiIO io = ImGui .getIO ();
139
140
@@ -142,6 +143,7 @@ private void initImGui() {
142
143
io .setBackendFlags (ImGuiBackendFlags .HasMouseCursors ); // Mouse cursors to display while resizing windows etc.
143
144
io .setBackendPlatformName ("imgui_java_impl_glfw" );
144
145
146
+ // ------------------------------------------------------------
145
147
// Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array.
146
148
final int [] keyMap = new int [ImGuiKey .COUNT ];
147
149
keyMap [ImGuiKey .Tab ] = GLFW_KEY_TAB ;
@@ -168,6 +170,7 @@ private void initImGui() {
168
170
keyMap [ImGuiKey .Z ] = GLFW_KEY_Z ;
169
171
io .setKeyMap (keyMap );
170
172
173
+ // ------------------------------------------------------------
171
174
// Mouse cursors mapping
172
175
mouseCursors [ImGuiMouseCursor .Arrow ] = glfwCreateStandardCursor (GLFW_ARROW_CURSOR );
173
176
mouseCursors [ImGuiMouseCursor .TextInput ] = glfwCreateStandardCursor (GLFW_IBEAM_CURSOR );
@@ -180,7 +183,7 @@ private void initImGui() {
180
183
mouseCursors [ImGuiMouseCursor .NotAllowed ] = glfwCreateStandardCursor (GLFW_ARROW_CURSOR );
181
184
182
185
// ------------------------------------------------------------
183
- // Here goes GLFW callbacks to update user input in Dear ImGui
186
+ // GLFW callbacks to handle user input
184
187
185
188
glfwSetKeyCallback (windowPtr , (w , key , scancode , action , mods ) -> {
186
189
if (action == GLFW_PRESS ) {
@@ -238,52 +241,51 @@ public String get() {
238
241
239
242
// ------------------------------------------------------------
240
243
// Fonts configuration
241
-
242
- // -------------------
243
- // Fonts merge example
244
+ // Read: https://raw.githubusercontent.com/ocornut/imgui/master/docs/FONTS.txt
244
245
245
246
final ImFontAtlas fontAtlas = io .getFonts ();
247
+ final ImFontConfig fontConfig = new ImFontConfig (); // Natively allocated object, should be explicitly destroyed
248
+
249
+ // Glyphs could be added per-font as well as per config used globally like here
250
+ fontConfig .setGlyphRanges (fontAtlas .getGlyphRangesCyrillic ());
246
251
247
- // First of all we add a default font, which is 'ProggyClean.ttf, 13px'
252
+ // Add a default font, which is 'ProggyClean.ttf, 13px'
248
253
fontAtlas .addFontDefault ();
249
254
250
- final ImFontConfig fontConfig = new ImFontConfig (); // Keep in mind that creation of the ImFontConfig will allocate the native memory
251
- fontConfig .setMergeMode (true ); // All fonts added while this mode is turned on will be merged with the previously added font
255
+ // Fonts merge example
256
+ fontConfig .setMergeMode (true ); // When enabled, all fonts added with this config would be merged with the previously added font
252
257
fontConfig .setPixelSnapH (true );
253
- fontConfig .setGlyphRanges (fontAtlas .getGlyphRangesCyrillic ()); // Additional glyphs could be added like this or in "addFontFrom*()" methods
254
258
255
- // We merge font loaded from resources with the default one. Thus we will get an absent cyrillic glyphs
256
259
fontAtlas .addFontFromMemoryTTF (loadFromResources ("basis33.ttf" ), 16 , fontConfig );
257
260
258
- // Disable merge mode and add all other fonts normally
259
261
fontConfig .setMergeMode (false );
260
262
fontConfig .setPixelSnapH (false );
261
263
262
- // ------------------------------
263
264
// Fonts from file/memory example
265
+ // We can add new fonts from the file system
266
+ fontAtlas .addFontFromFileTTF ("src/test/resources/Righteous-Regular.ttf" , 14 , fontConfig );
267
+ fontAtlas .addFontFromFileTTF ("src/test/resources/Righteous-Regular.ttf" , 16 , fontConfig );
264
268
265
- fontConfig .setRasterizerMultiply (1.2f ); // This will make fonts a bit more readable
266
-
267
- // We can add new fonts directly from file
268
- fontAtlas .addFontFromFileTTF ("src/test/resources/DroidSans.ttf" , 13 , fontConfig );
269
- fontAtlas .addFontFromFileTTF ("src/test/resources/DroidSans.ttf" , 14 , fontConfig );
270
-
271
- // Or directly from memory
272
- fontConfig .setName ("Roboto-Regular.ttf, 13px" ); // This name will be displayed in Style Editor
273
- fontAtlas .addFontFromMemoryTTF (loadFromResources ("Roboto-Regular.ttf" ), 13 , fontConfig );
274
- fontConfig .setName ("Roboto-Regular.ttf, 14px" ); // We can apply a new config value every time we add a new font
269
+ // Or directly from the memory
270
+ fontConfig .setName ("Roboto-Regular.ttf, 14px" ); // This name will be displayed in Style Editor
275
271
fontAtlas .addFontFromMemoryTTF (loadFromResources ("Roboto-Regular.ttf" ), 14 , fontConfig );
272
+ fontConfig .setName ("Roboto-Regular.ttf, 16px" ); // We can apply a new config value every time we add a new font
273
+ fontAtlas .addFontFromMemoryTTF (loadFromResources ("Roboto-Regular.ttf" ), 16 , fontConfig );
276
274
277
275
fontConfig .destroy (); // After all fonts were added we don't need this config more
278
276
277
+ // ------------------------------------------------------------
278
+ // Use freetype instead of stb_truetype to build a fonts texture
279
+ ImGuiFreeType .buildFontAtlas (fontAtlas , ImGuiFreeType .RasterizerFlags .LightHinting );
280
+
279
281
// Method initializes LWJGL3 renderer.
280
282
// This method SHOULD be called after you've initialized your ImGui configuration (fonts and so on).
281
283
// ImGui context should be created as well.
282
284
imGuiGl3 .init (glslVersion );
283
285
}
284
286
285
287
// Main application loop
286
- private void loop () throws Exception {
288
+ private void loop () {
287
289
double time = 0 ; // to track our frame delta value
288
290
289
291
// Run the rendering loop until the user has attempted to close the window
@@ -295,7 +297,7 @@ private void loop() throws Exception {
295
297
296
298
startFrame ((float ) deltaTime );
297
299
298
- // Any Dear ImGui code SHOULD go between NewFrame ()/Render () methods
300
+ // Any Dear ImGui code SHOULD go between ImGui.newFrame ()/ImGui.render () methods
299
301
ImGui .newFrame ();
300
302
exampleUi .render ();
301
303
ImGui .render ();
@@ -309,32 +311,30 @@ private void startFrame(final float deltaTime) {
309
311
glClearColor (exampleUi .backgroundColor [0 ], exampleUi .backgroundColor [1 ], exampleUi .backgroundColor [2 ], 0.0f );
310
312
glClear (GL_COLOR_BUFFER_BIT );
311
313
312
- // Get window size properties and mouse position
314
+ // Get window properties and mouse position
313
315
glfwGetWindowSize (windowPtr , winWidth , winHeight );
314
316
glfwGetFramebufferSize (windowPtr , fbWidth , fbHeight );
315
317
glfwGetCursorPos (windowPtr , mousePosX , mousePosY );
316
318
317
- // We SHOULD call those methods to update ImGui state for current frame
319
+ // We SHOULD call those methods to update Dear ImGui state for the current frame
318
320
final ImGuiIO io = ImGui .getIO ();
319
321
io .setDisplaySize (winWidth [0 ], winHeight [0 ]);
320
322
io .setDisplayFramebufferScale ((float ) fbWidth [0 ] / winWidth [0 ], (float ) fbHeight [0 ] / winHeight [0 ]);
321
323
io .setMousePos ((float ) mousePosX [0 ], (float ) mousePosY [0 ]);
322
324
io .setDeltaTime (deltaTime );
323
325
324
- // Update mouse cursor
326
+ // Update the mouse cursor
325
327
final int imguiCursor = ImGui .getMouseCursor ();
326
328
glfwSetCursor (windowPtr , mouseCursors [imguiCursor ]);
327
329
glfwSetInputMode (windowPtr , GLFW_CURSOR , GLFW_CURSOR_NORMAL );
328
330
}
329
331
330
332
private void endFrame () {
331
- // After Dear ImGui prepared a draw data, we use it in LWJGL3 renderer.
333
+ // After Dear ImGui prepared a draw data, we use it in the LWJGL3 renderer.
332
334
// At that moment ImGui will be rendered to the current OpenGL context.
333
335
imGuiGl3 .render (ImGui .getDrawData ());
334
336
335
- glfwSwapBuffers (windowPtr ); // swap the color buffers
336
-
337
- // Poll for window events. The key callback above will only be invoked during this call.
337
+ glfwSwapBuffers (windowPtr );
338
338
glfwPollEvents ();
339
339
}
340
340
0 commit comments