• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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