GLFW - Introduction To The API
GLFW - Introduction To The API
Table of Contents
This guide introduces the basic concepts of GLFW and describes initialization, error handling and API
guarantees and limitations. For a broad but shallow tutorial, see Getting started instead. For details on a
specific function in this category, see the Initialization, version and error reference.
Window guide
Context guide
Vulkan guide
Monitor guide
Input guide
Only the following functions may be called before the library has been successfully initialized, and only
from the main thread.
glfwGetVersion
glfwGetVersionString
glfwGetError
glfwSetErrorCallback
glfwInitHint
glfwInit
glfwTerminate
Calling any other function before successful initialization will cause a GLFW_NOT_INITIALIZED error.
Initializing GLFW
The library is initialized with glfwInit, which returns GLFW_FALSE if an error occurred.
if (!glfwInit())
{
// Handle initialization failure
}
If any part of initialization fails, any parts that succeeded are terminated as if glfwTerminate had been
called. The library only needs to be initialized once and additional calls to an already initialized library will
return GLFW_TRUE immediately.
Once the library has been successfully initialized, it should be terminated before the application exits.
Modern systems are very good at freeing resources allocated by programs that exit, but GLFW
sometimes has to change global system settings and these might not be restored without termination.
Initialization hints
Initialization hints are set before glfwInit and affect how the library behaves until termination. Hints are
set with glfwInitHint.
glfwInitHint(GLFW_JOYSTICK_HAT_BUTTONS, GLFW_FALSE);
The values you set hints to are never reset by GLFW, but they only take effect during initialization. Once
GLFW has been initialized, any values you set will be ignored until the library is terminated and initialized
again.
Some hints are platform specific. These may be set on any platform but they will only affect their specific
platform. Other platforms will ignore them. Setting these hints requires no platform specific headers or
functions.
GLFW_COCOA_MENUBAR specifies whether to create a basic menu bar, either from a nib or manually,
when the first window is created, which is when AppKit is initialized. Set this with glfwInitHint.
Terminating GLFW
Before your application exits, you should terminate the GLFW library if it has been initialized. This is done
with glfwTerminate.
glfwTerminate();
This will destroy any remaining window, monitor and cursor objects, restore any modified gamma ramps,
re-enable the screensaver if it had been disabled and free any other resources allocated by GLFW.
Once the library is terminated, it is as if it had never been initialized and you will need to initialize it again
before being able to use GLFW. If the library was not initialized or had already been terminated, it return
immediately.
Error handling
Some GLFW functions have return values that indicate an error, but this is often not very helpful when
trying to figure out what happened or why it occurred. Other functions have no return value reserved for
errors, so error notification needs a separate channel. Finally, far from all GLFW functions have return
values.
The last error code for the calling thread can be queried at any time with glfwGetError.
if (code != GLFW_NO_ERROR)
handle_error(code);
If no error has occurred since the last call, GLFW_NO_ERROR (zero) is returned. The error is cleared
before the function returns.
The error code indicates the general category of the error. Some error codes, such as
GLFW_NOT_INITIALIZED has only a single meaning, whereas others like GLFW_PLATFORM_ERROR
are used for many different errors.
GLFW often has more information about an error than its general category. You can retrieve a UTF-8
encoded human-readable description along with the error code. If no error has occurred since the last
call, the description is set to NULL.
if (description)
display_error_message(code, description);
The retrieved description string is only valid until the next error occurs. This means you must make a copy
of it if you want to keep it.
You can also set an error callback, which will be called each time an error occurs. It is set with
glfwSetErrorCallback.
glfwSetErrorCallback(error_callback);
The error callback receives the same error code and human-readable description returned by
glfwGetError.
The error callback is called after the error is stored, so calling glfwGetError from within the error callback
returns the same values as the callback argument.
The description string passed to the callback is only valid until the error callback returns. This means you
must make a copy of it if you want to keep it.
Reported errors are never fatal. As long as GLFW was successfully initialized, it will remain initialized
and in a safe state until terminated regardless of how many errors occur. If an error occurs during
initialization that causes glfwInit to fail, any part of the library that was initialized will be safely terminated.
Do not rely on a currently invalid call to generate a specific error, as in the future that same call may
generate a different error or become valid.
Coordinate systems
GLFW has two primary coordinate systems: the virtual screen and the window content area or content
area. Both use the same unit: virtual screen coordinates, or just screen coordinates, which don't
necessarily correspond to pixels.
Both the virtual screen and the content area coordinate systems have the X-axis pointing to the right and
the Y-axis pointing down.
Window and monitor positions are specified as the position of the upper-left corners of their content areas
relative to the virtual screen, while cursor positions are specified relative to a window's content area.
Because the origin of the window's content area coordinate system is also the point from which the
window position is specified, you can translate content area coordinates to the virtual screen by adding
the window position. The window frame, when present, extends out from the content area but does not
affect the window position.
Almost all positions and sizes in GLFW are measured in screen coordinates relative to one of the two
origins above. This includes cursor positions, window positions and sizes, window frame sizes, monitor
positions and video mode resolutions.
Two exceptions are the monitor physical size, which is measured in millimetres, and framebuffer size,
which is measured in pixels.
Pixels and screen coordinates may map 1:1 on your machine, but they won't on every other machine, for
example on a Mac with a Retina display. The ratio between screen coordinates and pixels may also
change at run-time depending on which monitor the window is currently considered to be on.
Pointer lifetimes
GLFW will never free any pointer you provide to it and you must never free any pointer it provides to you.
Many GLFW functions return pointers to dynamically allocated structures, strings or arrays, and some
callbacks are provided with strings or arrays. These are always managed by GLFW and should never be
freed by the application. The lifetime of these pointers is documented for each GLFW function and
callback. If you need to keep this data, you must copy it before its lifetime expires.
Many GLFW functions accept pointers to structures or strings allocated by the application. These are
never freed by GLFW and are always the responsibility of the application. If GLFW needs to keep the
data in these structures or strings, it is copied before the function returns.
Pointer lifetimes are guaranteed not to be shortened in future minor or patch releases.
Reentrancy
GLFW event processing and object destruction are not reentrant. This means that the following functions
must not be called from any callback function:
glfwDestroyWindow
glfwDestroyCursor
glfwPollEvents
glfwWaitEvents
glfwWaitEventsTimeout
glfwTerminate
These functions may be made reentrant in future minor or patch releases, but functions not on this list will
not be made non-reentrant.
Thread safety
Most GLFW functions must only be called from the main thread (the thread that calls main), but some
may be called from any thread once the library has been initialized. Before initialization the whole library
is thread-unsafe.
The reference documentation for every GLFW function states whether it is limited to the main thread.
Initialization, termination, event processing and the creation and destruction of windows, cursors and
OpenGL and OpenGL ES contexts are all restricted to the main thread due to limitations of one or several
platforms.
Because event processing must be performed on the main thread, all callbacks except for the error
callback will only be called on that thread. The error callback may be called on any thread, as any GLFW
function may generate errors.
The error code and description may be queried from any thread.
glfwGetError
glfwPostEmptyEvent
The window user pointer and close flag may be read and written from any thread, but this is not
synchronized by GLFW.
glfwGetWindowUserPointer
glfwSetWindowUserPointer
glfwWindowShouldClose
glfwSetWindowShouldClose
These functions for working with OpenGL and OpenGL ES contexts may be called from any thread, but
the window object is not synchronized by GLFW.
glfwMakeContextCurrent
glfwGetCurrentContext
glfwSwapBuffers
glfwSwapInterval
glfwExtensionSupported
glfwGetProcAddress
glfwGetTimerFrequency
glfwGetTimerValue
The regular timer may be used from any thread, but reading and writing the timer offset is not
synchronized by GLFW.
glfwGetTime
glfwSetTime
glfwGetVersion
glfwGetVersionString
glfwVulkanSupported
glfwGetRequiredInstanceExtensions
glfwGetInstanceProcAddress
glfwGetPhysicalDevicePresentationSupport
glfwCreateWindowSurface
GLFW uses synchronization objects internally only to manage the per-thread context and error states.
Additional synchronization is left to the application.
Functions that may currently be called from any thread will always remain so, but functions that are
currently limited to the main thread may be updated to allow calls from any thread in future releases.
Version compatibility
GLFW uses Semantic Versioning. This guarantees source and binary backward compatibility with earlier
minor versions of the API. This means that you can drop in a newer version of the library and existing
programs will continue to compile and existing binaries will continue to run.
Once a function or constant has been added, the signature of that function or value of that constant will
remain unchanged until the next major version of GLFW. No compatibility of any kind is guaranteed
between major versions.
Undocumented behavior, i.e. behavior that is not described in the documentation, may change at any
time until it is documented.
If the reference documentation and the implementation differ, the reference documentation will almost
always take precedence and the implementation will be fixed in the next release. The reference
documentation will also take precedence over anything stated in a guide.
Event order
The order of arrival of related events is not guaranteed to be consistent across platforms. The exception
is synthetic key and mouse button release events, which are always delivered after the window defocus
event.
Version management
GLFW provides mechanisms for identifying what version of GLFW your application was compiled against
as well as what version it is currently running against. If you are loading GLFW dynamically (not just
linking dynamically), you can use this to verify that the library binary is compatible with your application.
Compile-time version
The compile-time version of GLFW is provided by the GLFW header with the GLFW_VERSION_MAJOR,
GLFW_VERSION_MINOR and GLFW_VERSION_REVISION macros.
Run-time version
The run-time version can be retrieved with glfwGetVersion, a function that may be called regardless of
whether GLFW is initialized.
The version string is returned by glfwGetVersionString, a function that may be called regardless of
whether GLFW is initialized.
Do not use the version string to parse the GLFW library version. The glfwGetVersion function already
provides the version of the running library binary.
For example, when compiling GLFW 3.0 with MinGW using the Win32 and WGL back ends, the version
string may look something like this: