1b877906bSopenharmony_ci# Getting started {#quick_guide} 2b877906bSopenharmony_ci 3b877906bSopenharmony_ci[TOC] 4b877906bSopenharmony_ci 5b877906bSopenharmony_ciThis guide takes you through writing a small application using GLFW 3. The 6b877906bSopenharmony_ciapplication will create a window and OpenGL context, render a rotating triangle 7b877906bSopenharmony_ciand exit when the user closes the window or presses _Escape_. This guide will 8b877906bSopenharmony_ciintroduce a few of the most commonly used functions, but there are many more. 9b877906bSopenharmony_ci 10b877906bSopenharmony_ciThis guide assumes no experience with earlier versions of GLFW. If you 11b877906bSopenharmony_cihave used GLFW 2 in the past, read @ref moving_guide, as some functions 12b877906bSopenharmony_cibehave differently in GLFW 3. 13b877906bSopenharmony_ci 14b877906bSopenharmony_ci 15b877906bSopenharmony_ci## Step by step {#quick_steps} 16b877906bSopenharmony_ci 17b877906bSopenharmony_ci### Including the GLFW header {#quick_include} 18b877906bSopenharmony_ci 19b877906bSopenharmony_ciIn the source files of your application where you use GLFW, you need to include 20b877906bSopenharmony_ciits header file. 21b877906bSopenharmony_ci 22b877906bSopenharmony_ci```c 23b877906bSopenharmony_ci#include <GLFW/glfw3.h> 24b877906bSopenharmony_ci``` 25b877906bSopenharmony_ci 26b877906bSopenharmony_ciThis header provides all the constants, types and function prototypes of the 27b877906bSopenharmony_ciGLFW API. 28b877906bSopenharmony_ci 29b877906bSopenharmony_ciBy default it also includes the OpenGL header from your development environment. 30b877906bSopenharmony_ciOn some platforms this header only supports older versions of OpenGL. The most 31b877906bSopenharmony_ciextreme case is Windows, where it typically only supports OpenGL 1.2. 32b877906bSopenharmony_ci 33b877906bSopenharmony_ciMost programs will instead use an 34b877906bSopenharmony_ci[extension loader library](@ref context_glext_auto) and include its header. 35b877906bSopenharmony_ciThis example uses files generated by [glad](https://gen.glad.sh/). The GLFW 36b877906bSopenharmony_ciheader can detect most such headers if they are included first and will then not 37b877906bSopenharmony_ciinclude the one from your development environment. 38b877906bSopenharmony_ci 39b877906bSopenharmony_ci```c 40b877906bSopenharmony_ci#include <glad/gl.h> 41b877906bSopenharmony_ci#include <GLFW/glfw3.h> 42b877906bSopenharmony_ci``` 43b877906bSopenharmony_ci 44b877906bSopenharmony_ciTo make sure there will be no header conflicts, you can define @ref 45b877906bSopenharmony_ciGLFW_INCLUDE_NONE before the GLFW header to explicitly disable inclusion of the 46b877906bSopenharmony_cidevelopment environment header. This also allows the two headers to be included 47b877906bSopenharmony_ciin any order. 48b877906bSopenharmony_ci 49b877906bSopenharmony_ci```c 50b877906bSopenharmony_ci#define GLFW_INCLUDE_NONE 51b877906bSopenharmony_ci#include <GLFW/glfw3.h> 52b877906bSopenharmony_ci#include <glad/gl.h> 53b877906bSopenharmony_ci``` 54b877906bSopenharmony_ci 55b877906bSopenharmony_ci 56b877906bSopenharmony_ci### Initializing and terminating GLFW {#quick_init_term} 57b877906bSopenharmony_ci 58b877906bSopenharmony_ciBefore you can use most GLFW functions, the library must be initialized. On 59b877906bSopenharmony_cisuccessful initialization, `GLFW_TRUE` is returned. If an error occurred, 60b877906bSopenharmony_ci`GLFW_FALSE` is returned. 61b877906bSopenharmony_ci 62b877906bSopenharmony_ci```c 63b877906bSopenharmony_ciif (!glfwInit()) 64b877906bSopenharmony_ci{ 65b877906bSopenharmony_ci // Initialization failed 66b877906bSopenharmony_ci} 67b877906bSopenharmony_ci``` 68b877906bSopenharmony_ci 69b877906bSopenharmony_ciNote that `GLFW_TRUE` and `GLFW_FALSE` are and will always be one and zero. 70b877906bSopenharmony_ci 71b877906bSopenharmony_ciWhen you are done using GLFW, typically just before the application exits, you 72b877906bSopenharmony_cineed to terminate GLFW. 73b877906bSopenharmony_ci 74b877906bSopenharmony_ci```c 75b877906bSopenharmony_ciglfwTerminate(); 76b877906bSopenharmony_ci``` 77b877906bSopenharmony_ci 78b877906bSopenharmony_ciThis destroys any remaining windows and releases any other resources allocated by 79b877906bSopenharmony_ciGLFW. After this call, you must initialize GLFW again before using any GLFW 80b877906bSopenharmony_cifunctions that require it. 81b877906bSopenharmony_ci 82b877906bSopenharmony_ci 83b877906bSopenharmony_ci### Setting an error callback {#quick_capture_error} 84b877906bSopenharmony_ci 85b877906bSopenharmony_ciMost events are reported through callbacks, whether it's a key being pressed, 86b877906bSopenharmony_cia GLFW window being moved, or an error occurring. Callbacks are C functions (or 87b877906bSopenharmony_ciC++ static methods) that are called by GLFW with arguments describing the event. 88b877906bSopenharmony_ci 89b877906bSopenharmony_ciIn case a GLFW function fails, an error is reported to the GLFW error callback. 90b877906bSopenharmony_ciYou can receive these reports with an error callback. This function must have 91b877906bSopenharmony_cithe signature below but may do anything permitted in other callbacks. 92b877906bSopenharmony_ci 93b877906bSopenharmony_ci```c 94b877906bSopenharmony_civoid error_callback(int error, const char* description) 95b877906bSopenharmony_ci{ 96b877906bSopenharmony_ci fprintf(stderr, "Error: %s\n", description); 97b877906bSopenharmony_ci} 98b877906bSopenharmony_ci``` 99b877906bSopenharmony_ci 100b877906bSopenharmony_ciCallback functions must be set, so GLFW knows to call them. The function to set 101b877906bSopenharmony_cithe error callback is one of the few GLFW functions that may be called before 102b877906bSopenharmony_ciinitialization, which lets you be notified of errors both during and after 103b877906bSopenharmony_ciinitialization. 104b877906bSopenharmony_ci 105b877906bSopenharmony_ci```c 106b877906bSopenharmony_ciglfwSetErrorCallback(error_callback); 107b877906bSopenharmony_ci``` 108b877906bSopenharmony_ci 109b877906bSopenharmony_ci 110b877906bSopenharmony_ci### Creating a window and context {#quick_create_window} 111b877906bSopenharmony_ci 112b877906bSopenharmony_ciThe window and its OpenGL context are created with a single call to @ref 113b877906bSopenharmony_ciglfwCreateWindow, which returns a handle to the created combined window and 114b877906bSopenharmony_cicontext object 115b877906bSopenharmony_ci 116b877906bSopenharmony_ci```c 117b877906bSopenharmony_ciGLFWwindow* window = glfwCreateWindow(640, 480, "My Title", NULL, NULL); 118b877906bSopenharmony_ciif (!window) 119b877906bSopenharmony_ci{ 120b877906bSopenharmony_ci // Window or OpenGL context creation failed 121b877906bSopenharmony_ci} 122b877906bSopenharmony_ci``` 123b877906bSopenharmony_ci 124b877906bSopenharmony_ciThis creates a 640 by 480 windowed mode window with an OpenGL context. If 125b877906bSopenharmony_ciwindow or OpenGL context creation fails, `NULL` will be returned. You should 126b877906bSopenharmony_cialways check the return value. While window creation rarely fails, context 127b877906bSopenharmony_cicreation depends on properly installed drivers and may fail even on machines 128b877906bSopenharmony_ciwith the necessary hardware. 129b877906bSopenharmony_ci 130b877906bSopenharmony_ciBy default, the OpenGL context GLFW creates may have any version. You can 131b877906bSopenharmony_cirequire a minimum OpenGL version by setting the `GLFW_CONTEXT_VERSION_MAJOR` and 132b877906bSopenharmony_ci`GLFW_CONTEXT_VERSION_MINOR` hints _before_ creation. If the required minimum 133b877906bSopenharmony_civersion is not supported on the machine, context (and window) creation fails. 134b877906bSopenharmony_ci 135b877906bSopenharmony_ciYou can select the OpenGL profile by setting the `GLFW_OPENGL_PROFILE` hint. 136b877906bSopenharmony_ciThis program uses the core profile as that is the only profile macOS supports 137b877906bSopenharmony_cifor OpenGL 3.x and 4.x. 138b877906bSopenharmony_ci 139b877906bSopenharmony_ci```c 140b877906bSopenharmony_ciglfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); 141b877906bSopenharmony_ciglfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); 142b877906bSopenharmony_ciglfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 143b877906bSopenharmony_ciGLFWwindow* window = glfwCreateWindow(640, 480, "My Title", NULL, NULL); 144b877906bSopenharmony_ciif (!window) 145b877906bSopenharmony_ci{ 146b877906bSopenharmony_ci // Window or context creation failed 147b877906bSopenharmony_ci} 148b877906bSopenharmony_ci``` 149b877906bSopenharmony_ci 150b877906bSopenharmony_ciWhen a window and context is no longer needed, destroy it. 151b877906bSopenharmony_ci 152b877906bSopenharmony_ci```c 153b877906bSopenharmony_ciglfwDestroyWindow(window); 154b877906bSopenharmony_ci``` 155b877906bSopenharmony_ci 156b877906bSopenharmony_ciOnce this function is called, no more events will be delivered for that window 157b877906bSopenharmony_ciand its handle becomes invalid. 158b877906bSopenharmony_ci 159b877906bSopenharmony_ci 160b877906bSopenharmony_ci### Making the OpenGL context current {#quick_context_current} 161b877906bSopenharmony_ci 162b877906bSopenharmony_ciBefore you can use the OpenGL API, you must have a current OpenGL context. 163b877906bSopenharmony_ci 164b877906bSopenharmony_ci```c 165b877906bSopenharmony_ciglfwMakeContextCurrent(window); 166b877906bSopenharmony_ci``` 167b877906bSopenharmony_ci 168b877906bSopenharmony_ciThe context will remain current until you make another context current or until 169b877906bSopenharmony_cithe window owning the current context is destroyed. 170b877906bSopenharmony_ci 171b877906bSopenharmony_ciIf you are using an [extension loader library](@ref context_glext_auto) to 172b877906bSopenharmony_ciaccess modern OpenGL then this is when to initialize it, as the loader needs 173b877906bSopenharmony_cia current context to load from. This example uses 174b877906bSopenharmony_ci[glad](https://github.com/Dav1dde/glad), but the same rule applies to all such 175b877906bSopenharmony_cilibraries. 176b877906bSopenharmony_ci 177b877906bSopenharmony_ci```c 178b877906bSopenharmony_cigladLoadGL(glfwGetProcAddress); 179b877906bSopenharmony_ci``` 180b877906bSopenharmony_ci 181b877906bSopenharmony_ci 182b877906bSopenharmony_ci### Checking the window close flag {#quick_window_close} 183b877906bSopenharmony_ci 184b877906bSopenharmony_ciEach window has a flag indicating whether the window should be closed. 185b877906bSopenharmony_ci 186b877906bSopenharmony_ciWhen the user attempts to close the window, either by pressing the close widget 187b877906bSopenharmony_ciin the title bar or using a key combination like Alt+F4, this flag is set to 1. 188b877906bSopenharmony_ciNote that __the window isn't actually closed__, so you are expected to monitor 189b877906bSopenharmony_cithis flag and either destroy the window or give some kind of feedback to the 190b877906bSopenharmony_ciuser. 191b877906bSopenharmony_ci 192b877906bSopenharmony_ci```c 193b877906bSopenharmony_ciwhile (!glfwWindowShouldClose(window)) 194b877906bSopenharmony_ci{ 195b877906bSopenharmony_ci // Keep running 196b877906bSopenharmony_ci} 197b877906bSopenharmony_ci``` 198b877906bSopenharmony_ci 199b877906bSopenharmony_ciYou can be notified when the user is attempting to close the window by setting 200b877906bSopenharmony_cia close callback with @ref glfwSetWindowCloseCallback. The callback will be 201b877906bSopenharmony_cicalled immediately after the close flag has been set. 202b877906bSopenharmony_ci 203b877906bSopenharmony_ciYou can also set it yourself with @ref glfwSetWindowShouldClose. This can be 204b877906bSopenharmony_ciuseful if you want to interpret other kinds of input as closing the window, like 205b877906bSopenharmony_cifor example pressing the _Escape_ key. 206b877906bSopenharmony_ci 207b877906bSopenharmony_ci 208b877906bSopenharmony_ci### Receiving input events {#quick_key_input} 209b877906bSopenharmony_ci 210b877906bSopenharmony_ciEach window has a large number of callbacks that can be set to receive all the 211b877906bSopenharmony_civarious kinds of events. To receive key press and release events, create a key 212b877906bSopenharmony_cicallback function. 213b877906bSopenharmony_ci 214b877906bSopenharmony_ci```c 215b877906bSopenharmony_cistatic void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) 216b877906bSopenharmony_ci{ 217b877906bSopenharmony_ci if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) 218b877906bSopenharmony_ci glfwSetWindowShouldClose(window, GLFW_TRUE); 219b877906bSopenharmony_ci} 220b877906bSopenharmony_ci``` 221b877906bSopenharmony_ci 222b877906bSopenharmony_ciThe key callback, like other window related callbacks, are set per-window. 223b877906bSopenharmony_ci 224b877906bSopenharmony_ci```c 225b877906bSopenharmony_ciglfwSetKeyCallback(window, key_callback); 226b877906bSopenharmony_ci``` 227b877906bSopenharmony_ci 228b877906bSopenharmony_ciIn order for event callbacks to be called when events occur, you need to process 229b877906bSopenharmony_cievents as described below. 230b877906bSopenharmony_ci 231b877906bSopenharmony_ci 232b877906bSopenharmony_ci### Rendering with OpenGL {#quick_render} 233b877906bSopenharmony_ci 234b877906bSopenharmony_ciOnce you have a current OpenGL context, you can use OpenGL normally. In this 235b877906bSopenharmony_citutorial, a multicolored rotating triangle will be rendered. The framebuffer 236b877906bSopenharmony_cisize needs to be retrieved for `glViewport`. 237b877906bSopenharmony_ci 238b877906bSopenharmony_ci```c 239b877906bSopenharmony_ciint width, height; 240b877906bSopenharmony_ciglfwGetFramebufferSize(window, &width, &height); 241b877906bSopenharmony_ciglViewport(0, 0, width, height); 242b877906bSopenharmony_ci``` 243b877906bSopenharmony_ci 244b877906bSopenharmony_ciYou can also set a framebuffer size callback using @ref 245b877906bSopenharmony_ciglfwSetFramebufferSizeCallback and be notified when the size changes. 246b877906bSopenharmony_ci 247b877906bSopenharmony_ciThe details of how to render with OpenGL is outside the scope of this tutorial, 248b877906bSopenharmony_cibut there are many excellent resources for learning modern OpenGL. Here are 249b877906bSopenharmony_cia few of them: 250b877906bSopenharmony_ci 251b877906bSopenharmony_ci - [Anton's OpenGL 4 Tutorials](https://antongerdelan.net/opengl/) 252b877906bSopenharmony_ci - [Learn OpenGL](https://learnopengl.com/) 253b877906bSopenharmony_ci - [Open.GL](https://open.gl/) 254b877906bSopenharmony_ci 255b877906bSopenharmony_ciThese all happen to use GLFW, but OpenGL itself works the same whatever API you 256b877906bSopenharmony_ciuse to create the window and context. 257b877906bSopenharmony_ci 258b877906bSopenharmony_ci 259b877906bSopenharmony_ci### Reading the timer {#quick_timer} 260b877906bSopenharmony_ci 261b877906bSopenharmony_ciTo create smooth animation, a time source is needed. GLFW provides a timer that 262b877906bSopenharmony_cireturns the number of seconds since initialization. The time source used is the 263b877906bSopenharmony_cimost accurate on each platform and generally has micro- or nanosecond 264b877906bSopenharmony_ciresolution. 265b877906bSopenharmony_ci 266b877906bSopenharmony_ci```c 267b877906bSopenharmony_cidouble time = glfwGetTime(); 268b877906bSopenharmony_ci``` 269b877906bSopenharmony_ci 270b877906bSopenharmony_ci 271b877906bSopenharmony_ci### Swapping buffers {#quick_swap_buffers} 272b877906bSopenharmony_ci 273b877906bSopenharmony_ciGLFW windows by default use double buffering. That means that each window has 274b877906bSopenharmony_citwo rendering buffers; a front buffer and a back buffer. The front buffer is 275b877906bSopenharmony_cithe one being displayed and the back buffer the one you render to. 276b877906bSopenharmony_ci 277b877906bSopenharmony_ciWhen the entire frame has been rendered, the buffers need to be swapped with one 278b877906bSopenharmony_cianother, so the back buffer becomes the front buffer and vice versa. 279b877906bSopenharmony_ci 280b877906bSopenharmony_ci```c 281b877906bSopenharmony_ciglfwSwapBuffers(window); 282b877906bSopenharmony_ci``` 283b877906bSopenharmony_ci 284b877906bSopenharmony_ciThe swap interval indicates how many frames to wait until swapping the buffers, 285b877906bSopenharmony_cicommonly known as _vsync_. By default, the swap interval is zero, meaning 286b877906bSopenharmony_cibuffer swapping will occur immediately. On fast machines, many of those frames 287b877906bSopenharmony_ciwill never be seen, as the screen is still only updated typically 60-75 times 288b877906bSopenharmony_ciper second, so this wastes a lot of CPU and GPU cycles. 289b877906bSopenharmony_ci 290b877906bSopenharmony_ciAlso, because the buffers will be swapped in the middle the screen update, 291b877906bSopenharmony_cileading to [screen tearing](https://en.wikipedia.org/wiki/Screen_tearing). 292b877906bSopenharmony_ci 293b877906bSopenharmony_ciFor these reasons, applications will typically want to set the swap interval to 294b877906bSopenharmony_cione. It can be set to higher values, but this is usually not recommended, 295b877906bSopenharmony_cibecause of the input latency it leads to. 296b877906bSopenharmony_ci 297b877906bSopenharmony_ci```c 298b877906bSopenharmony_ciglfwSwapInterval(1); 299b877906bSopenharmony_ci``` 300b877906bSopenharmony_ci 301b877906bSopenharmony_ciThis function acts on the current context and will fail unless a context is 302b877906bSopenharmony_cicurrent. 303b877906bSopenharmony_ci 304b877906bSopenharmony_ci 305b877906bSopenharmony_ci### Processing events {#quick_process_events} 306b877906bSopenharmony_ci 307b877906bSopenharmony_ciGLFW needs to communicate regularly with the window system both in order to 308b877906bSopenharmony_cireceive events and to show that the application hasn't locked up. Event 309b877906bSopenharmony_ciprocessing must be done regularly while you have visible windows and is normally 310b877906bSopenharmony_cidone each frame after buffer swapping. 311b877906bSopenharmony_ci 312b877906bSopenharmony_ciThere are two methods for processing pending events; polling and waiting. This 313b877906bSopenharmony_ciexample will use event polling, which processes only those events that have 314b877906bSopenharmony_cialready been received and then returns immediately. 315b877906bSopenharmony_ci 316b877906bSopenharmony_ci```c 317b877906bSopenharmony_ciglfwPollEvents(); 318b877906bSopenharmony_ci``` 319b877906bSopenharmony_ci 320b877906bSopenharmony_ciThis is the best choice when rendering continually, like most games do. If 321b877906bSopenharmony_ciinstead you only need to update your rendering once you have received new input, 322b877906bSopenharmony_ci@ref glfwWaitEvents is a better choice. It waits until at least one event has 323b877906bSopenharmony_cibeen received, putting the thread to sleep in the meantime, and then processes 324b877906bSopenharmony_ciall received events. This saves a great deal of CPU cycles and is useful for, 325b877906bSopenharmony_cifor example, many kinds of editing tools. 326b877906bSopenharmony_ci 327b877906bSopenharmony_ci 328b877906bSopenharmony_ci## Putting it together {#quick_example} 329b877906bSopenharmony_ci 330b877906bSopenharmony_ciNow that you know how to initialize GLFW, create a window and poll for 331b877906bSopenharmony_cikeyboard input, it's possible to create a small program. 332b877906bSopenharmony_ci 333b877906bSopenharmony_ciThis program creates a 640 by 480 windowed mode window and starts a loop that 334b877906bSopenharmony_ciclears the screen, renders a triangle and processes events until the user either 335b877906bSopenharmony_cipresses _Escape_ or closes the window. 336b877906bSopenharmony_ci 337b877906bSopenharmony_ci@snippet triangle-opengl.c code 338b877906bSopenharmony_ci 339b877906bSopenharmony_ciThe program above can be found in the [source package][download] as 340b877906bSopenharmony_ci`examples/triangle-opengl.c` and is compiled along with all other examples when 341b877906bSopenharmony_ciyou build GLFW. If you built GLFW from the source package then you already have 342b877906bSopenharmony_cithis as `triangle-opengl.exe` on Windows, `triangle-opengl` on Linux or 343b877906bSopenharmony_ci`triangle-opengl.app` on macOS. 344b877906bSopenharmony_ci 345b877906bSopenharmony_ci[download]: https://www.glfw.org/download.html 346b877906bSopenharmony_ci 347b877906bSopenharmony_ciThis tutorial used only a few of the many functions GLFW provides. There are 348b877906bSopenharmony_ciguides for each of the areas covered by GLFW. Each guide will introduce all the 349b877906bSopenharmony_cifunctions for that category. 350b877906bSopenharmony_ci 351b877906bSopenharmony_ci - @ref intro_guide 352b877906bSopenharmony_ci - @ref window_guide 353b877906bSopenharmony_ci - @ref context_guide 354b877906bSopenharmony_ci - @ref monitor_guide 355b877906bSopenharmony_ci - @ref input_guide 356b877906bSopenharmony_ci 357b877906bSopenharmony_ciYou can access reference documentation for any GLFW function by clicking it and 358b877906bSopenharmony_cithe reference for each function links to related functions and guide sections. 359b877906bSopenharmony_ci 360b877906bSopenharmony_ciThe tutorial ends here. Once you have written a program that uses GLFW, you 361b877906bSopenharmony_ciwill need to compile and link it. How to do that depends on the development 362b877906bSopenharmony_cienvironment you are using and is best explained by the documentation for that 363b877906bSopenharmony_cienvironment. To learn about the details that are specific to GLFW, see 364b877906bSopenharmony_ci@ref build_guide. 365b877906bSopenharmony_ci 366