mirror of
https://github.com/gwm17/glfw.git
synced 2024-11-26 20:28:49 -05:00
399c2a1fad
The documentation claims that any extension loader library header
included before the GLFW one will prevent the inclusion of the
default OpenGL header. In reality this only worked if the loader
defined the canonical desktop OpenGL __gl_h_ inclusion guard and even
then relied on the OpenGL header to detect this.
This is the companion to 105cf32e0b
, which
added the preprocessor logic to check for many known OpenGL and OpenGL
ES inclusion guards and not even attempt to include the default header
if any are present.
Some clarification of the language around header inclusion has also been
attempted, including making GLFW_INCLUDE_NONE more prominent.
Fixes #1695.
372 lines
12 KiB
Plaintext
372 lines
12 KiB
Plaintext
/*!
|
|
|
|
@page quick_guide Getting started
|
|
|
|
@tableofcontents
|
|
|
|
This guide takes you through writing a small application using GLFW 3. The
|
|
application will create a window and OpenGL context, render a rotating triangle
|
|
and exit when the user closes the window or presses _Escape_. This guide will
|
|
introduce a few of the most commonly used functions, but there are many more.
|
|
|
|
This guide assumes no experience with earlier versions of GLFW. If you
|
|
have used GLFW 2 in the past, read @ref moving_guide, as some functions
|
|
behave differently in GLFW 3.
|
|
|
|
|
|
@section quick_steps Step by step
|
|
|
|
@subsection quick_include Including the GLFW header
|
|
|
|
In the source files of your application where you use GLFW, you need to include
|
|
its header file.
|
|
|
|
@code
|
|
#include <GLFW/glfw3.h>
|
|
@endcode
|
|
|
|
This header provides all the constants, types and function prototypes of the
|
|
GLFW API.
|
|
|
|
By default it also includes the OpenGL header from your development environment.
|
|
On some platforms this header only supports older versions of OpenGL. The most
|
|
extreme case is Windows, where it typically only supports OpenGL 1.2.
|
|
|
|
Most programs will instead use an
|
|
[extension loader library](@ref context_glext_auto) and include its header.
|
|
This example uses files generated by [glad](https://gen.glad.sh/). The GLFW
|
|
header can detect most such headers if they are included first and will then not
|
|
include the one from your development environment.
|
|
|
|
@code
|
|
#include <glad/gl.h>
|
|
#include <GLFW/glfw3.h>
|
|
@endcode
|
|
|
|
To make sure there will be no header conflicts, you can define @ref
|
|
GLFW_INCLUDE_NONE before the GLFW header to explicitly disable inclusion of the
|
|
development environment header. This also allows the two headers to be included
|
|
in any order.
|
|
|
|
@code
|
|
#define GLFW_INCLUDE_NONE
|
|
#include <GLFW/glfw3.h>
|
|
#include <glad/gl.h>
|
|
@endcode
|
|
|
|
|
|
@subsection quick_init_term Initializing and terminating GLFW
|
|
|
|
Before you can use most GLFW functions, the library must be initialized. On
|
|
successful initialization, `GLFW_TRUE` is returned. If an error occurred,
|
|
`GLFW_FALSE` is returned.
|
|
|
|
@code
|
|
if (!glfwInit())
|
|
{
|
|
// Initialization failed
|
|
}
|
|
@endcode
|
|
|
|
Note that `GLFW_TRUE` and `GLFW_FALSE` are and will always be one and zero.
|
|
|
|
When you are done using GLFW, typically just before the application exits, you
|
|
need to terminate GLFW.
|
|
|
|
@code
|
|
glfwTerminate();
|
|
@endcode
|
|
|
|
This destroys any remaining windows and releases any other resources allocated by
|
|
GLFW. After this call, you must initialize GLFW again before using any GLFW
|
|
functions that require it.
|
|
|
|
|
|
@subsection quick_capture_error Setting an error callback
|
|
|
|
Most events are reported through callbacks, whether it's a key being pressed,
|
|
a GLFW window being moved, or an error occurring. Callbacks are C functions (or
|
|
C++ static methods) that are called by GLFW with arguments describing the event.
|
|
|
|
In case a GLFW function fails, an error is reported to the GLFW error callback.
|
|
You can receive these reports with an error callback. This function must have
|
|
the signature below but may do anything permitted in other callbacks.
|
|
|
|
@code
|
|
void error_callback(int error, const char* description)
|
|
{
|
|
fprintf(stderr, "Error: %s\n", description);
|
|
}
|
|
@endcode
|
|
|
|
Callback functions must be set, so GLFW knows to call them. The function to set
|
|
the error callback is one of the few GLFW functions that may be called before
|
|
initialization, which lets you be notified of errors both during and after
|
|
initialization.
|
|
|
|
@code
|
|
glfwSetErrorCallback(error_callback);
|
|
@endcode
|
|
|
|
|
|
@subsection quick_create_window Creating a window and context
|
|
|
|
The window and its OpenGL context are created with a single call to @ref
|
|
glfwCreateWindow, which returns a handle to the created combined window and
|
|
context object
|
|
|
|
@code
|
|
GLFWwindow* window = glfwCreateWindow(640, 480, "My Title", NULL, NULL);
|
|
if (!window)
|
|
{
|
|
// Window or OpenGL context creation failed
|
|
}
|
|
@endcode
|
|
|
|
This creates a 640 by 480 windowed mode window with an OpenGL context. If
|
|
window or OpenGL context creation fails, `NULL` will be returned. You should
|
|
always check the return value. While window creation rarely fails, context
|
|
creation depends on properly installed drivers and may fail even on machines
|
|
with the necessary hardware.
|
|
|
|
By default, the OpenGL context GLFW creates may have any version. You can
|
|
require a minimum OpenGL version by setting the `GLFW_CONTEXT_VERSION_MAJOR` and
|
|
`GLFW_CONTEXT_VERSION_MINOR` hints _before_ creation. If the required minimum
|
|
version is not supported on the machine, context (and window) creation fails.
|
|
|
|
You can select the OpenGL profile by setting the `GLFW_OPENGL_PROFILE` hint.
|
|
This program uses the core profile as that is the only profile macOS supports
|
|
for OpenGL 3.x and 4.x.
|
|
|
|
@code
|
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
|
GLFWwindow* window = glfwCreateWindow(640, 480, "My Title", NULL, NULL);
|
|
if (!window)
|
|
{
|
|
// Window or context creation failed
|
|
}
|
|
@endcode
|
|
|
|
The window handle is passed to all window related functions and is provided to
|
|
along to all window related callbacks, so they can tell which window received
|
|
the event.
|
|
|
|
When a window and context is no longer needed, destroy it.
|
|
|
|
@code
|
|
glfwDestroyWindow(window);
|
|
@endcode
|
|
|
|
Once this function is called, no more events will be delivered for that window
|
|
and its handle becomes invalid.
|
|
|
|
|
|
@subsection quick_context_current Making the OpenGL context current
|
|
|
|
Before you can use the OpenGL API, you must have a current OpenGL context.
|
|
|
|
@code
|
|
glfwMakeContextCurrent(window);
|
|
@endcode
|
|
|
|
The context will remain current until you make another context current or until
|
|
the window owning the current context is destroyed.
|
|
|
|
If you are using an [extension loader library](@ref context_glext_auto) to
|
|
access modern OpenGL then this is when to initialize it, as the loader needs
|
|
a current context to load from. This example uses
|
|
[glad](https://github.com/Dav1dde/glad), but the same rule applies to all such
|
|
libraries.
|
|
|
|
@code
|
|
gladLoadGL(glfwGetProcAddress);
|
|
@endcode
|
|
|
|
|
|
@subsection quick_window_close Checking the window close flag
|
|
|
|
Each window has a flag indicating whether the window should be closed.
|
|
|
|
When the user attempts to close the window, either by pressing the close widget
|
|
in the title bar or using a key combination like Alt+F4, this flag is set to 1.
|
|
Note that __the window isn't actually closed__, so you are expected to monitor
|
|
this flag and either destroy the window or give some kind of feedback to the
|
|
user.
|
|
|
|
@code
|
|
while (!glfwWindowShouldClose(window))
|
|
{
|
|
// Keep running
|
|
}
|
|
@endcode
|
|
|
|
You can be notified when the user is attempting to close the window by setting
|
|
a close callback with @ref glfwSetWindowCloseCallback. The callback will be
|
|
called immediately after the close flag has been set.
|
|
|
|
You can also set it yourself with @ref glfwSetWindowShouldClose. This can be
|
|
useful if you want to interpret other kinds of input as closing the window, like
|
|
for example pressing the _Escape_ key.
|
|
|
|
|
|
@subsection quick_key_input Receiving input events
|
|
|
|
Each window has a large number of callbacks that can be set to receive all the
|
|
various kinds of events. To receive key press and release events, create a key
|
|
callback function.
|
|
|
|
@code
|
|
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
|
|
{
|
|
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
|
|
glfwSetWindowShouldClose(window, GLFW_TRUE);
|
|
}
|
|
@endcode
|
|
|
|
The key callback, like other window related callbacks, are set per-window.
|
|
|
|
@code
|
|
glfwSetKeyCallback(window, key_callback);
|
|
@endcode
|
|
|
|
In order for event callbacks to be called when events occur, you need to process
|
|
events as described below.
|
|
|
|
|
|
@subsection quick_render Rendering with OpenGL
|
|
|
|
Once you have a current OpenGL context, you can use OpenGL normally. In this
|
|
tutorial, a multi-colored rotating triangle will be rendered. The framebuffer
|
|
size needs to be retrieved for `glViewport`.
|
|
|
|
@code
|
|
int width, height;
|
|
glfwGetFramebufferSize(window, &width, &height);
|
|
glViewport(0, 0, width, height);
|
|
@endcode
|
|
|
|
You can also set a framebuffer size callback using @ref
|
|
glfwSetFramebufferSizeCallback and be notified when the size changes.
|
|
|
|
The details of how to render with OpenGL is outside the scope of this tutorial,
|
|
but there are many excellent resources for learning modern OpenGL. Here are
|
|
a few of them:
|
|
|
|
- [Anton's OpenGL 4 Tutorials](https://antongerdelan.net/opengl/)
|
|
- [Learn OpenGL](https://learnopengl.com/)
|
|
- [Open.GL](https://open.gl/)
|
|
|
|
These all happen to use GLFW, but OpenGL itself works the same whatever API you
|
|
use to create the window and context.
|
|
|
|
|
|
@subsection quick_timer Reading the timer
|
|
|
|
To create smooth animation, a time source is needed. GLFW provides a timer that
|
|
returns the number of seconds since initialization. The time source used is the
|
|
most accurate on each platform and generally has micro- or nanosecond
|
|
resolution.
|
|
|
|
@code
|
|
double time = glfwGetTime();
|
|
@endcode
|
|
|
|
|
|
@subsection quick_swap_buffers Swapping buffers
|
|
|
|
GLFW windows by default use double buffering. That means that each window has
|
|
two rendering buffers; a front buffer and a back buffer. The front buffer is
|
|
the one being displayed and the back buffer the one you render to.
|
|
|
|
When the entire frame has been rendered, the buffers need to be swapped with one
|
|
another, so the back buffer becomes the front buffer and vice versa.
|
|
|
|
@code
|
|
glfwSwapBuffers(window);
|
|
@endcode
|
|
|
|
The swap interval indicates how many frames to wait until swapping the buffers,
|
|
commonly known as _vsync_. By default, the swap interval is zero, meaning
|
|
buffer swapping will occur immediately. On fast machines, many of those frames
|
|
will never be seen, as the screen is still only updated typically 60-75 times
|
|
per second, so this wastes a lot of CPU and GPU cycles.
|
|
|
|
Also, because the buffers will be swapped in the middle the screen update,
|
|
leading to [screen tearing](https://en.wikipedia.org/wiki/Screen_tearing).
|
|
|
|
For these reasons, applications will typically want to set the swap interval to
|
|
one. It can be set to higher values, but this is usually not recommended,
|
|
because of the input latency it leads to.
|
|
|
|
@code
|
|
glfwSwapInterval(1);
|
|
@endcode
|
|
|
|
This function acts on the current context and will fail unless a context is
|
|
current.
|
|
|
|
|
|
@subsection quick_process_events Processing events
|
|
|
|
GLFW needs to communicate regularly with the window system both in order to
|
|
receive events and to show that the application hasn't locked up. Event
|
|
processing must be done regularly while you have visible windows and is normally
|
|
done each frame after buffer swapping.
|
|
|
|
There are two methods for processing pending events; polling and waiting. This
|
|
example will use event polling, which processes only those events that have
|
|
already been received and then returns immediately.
|
|
|
|
@code
|
|
glfwPollEvents();
|
|
@endcode
|
|
|
|
This is the best choice when rendering continually, like most games do. If
|
|
instead you only need to update your rendering once you have received new input,
|
|
@ref glfwWaitEvents is a better choice. It waits until at least one event has
|
|
been received, putting the thread to sleep in the meantime, and then processes
|
|
all received events. This saves a great deal of CPU cycles and is useful for,
|
|
for example, many kinds of editing tools.
|
|
|
|
|
|
@section quick_example Putting it together
|
|
|
|
Now that you know how to initialize GLFW, create a window and poll for
|
|
keyboard input, it's possible to create a small program.
|
|
|
|
This program creates a 640 by 480 windowed mode window and starts a loop that
|
|
clears the screen, renders a triangle and processes events until the user either
|
|
presses _Escape_ or closes the window.
|
|
|
|
@snippet triangle-opengl.c code
|
|
|
|
The program above can be found in the
|
|
[source package](https://www.glfw.org/download.html) as
|
|
`examples/triangle-opengl.c` and is compiled along with all other examples when
|
|
you build GLFW. If you built GLFW from the source package then you already have
|
|
this as `triangle-opengl.exe` on Windows, `triangle-opengl` on Linux or
|
|
`triangle-opengl.app` on macOS.
|
|
|
|
This tutorial used only a few of the many functions GLFW provides. There are
|
|
guides for each of the areas covered by GLFW. Each guide will introduce all the
|
|
functions for that category.
|
|
|
|
- @ref intro_guide
|
|
- @ref window_guide
|
|
- @ref context_guide
|
|
- @ref monitor_guide
|
|
- @ref input_guide
|
|
|
|
You can access reference documentation for any GLFW function by clicking it and
|
|
the reference for each function links to related functions and guide sections.
|
|
|
|
The tutorial ends here. Once you have written a program that uses GLFW, you
|
|
will need to compile and link it. How to do that depends on the development
|
|
environment you are using and is best explained by the documentation for that
|
|
environment. To learn about the details that are specific to GLFW, see
|
|
@ref build_guide.
|
|
|
|
*/
|