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