glfw/docs/quick.dox

348 lines
12 KiB
Plaintext
Raw Normal View History

/*!
2014-09-18 15:03:29 +02:00
@page quick Getting started
2013-03-12 18:57:38 +01:00
@tableofcontents
2014-09-18 15:03:29 +02:00
This guide takes you through writing a simple 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.
2013-03-29 14:06:23 +01:00
This guide assumes no experience with earlier versions of GLFW. If you
2014-09-18 15:03:29 +02:00
have used GLFW 2 in the past, read the @ref moving guide, as some functions
behave differently in GLFW 3.
2013-03-29 14:06:23 +01:00
2014-09-18 15:03:29 +02:00
@section quick_steps Step by step
2014-09-18 15:03:29 +02:00
@subsection quick_include Including the GLFW header
In the source files of your application where you use OpenGL or GLFW, you need
to include the GLFW 3 header file.
@code
#include <GLFW/glfw3.h>
@endcode
2013-02-28 21:15:04 +01:00
This defines all the constants, types and function prototypes of the GLFW API.
2015-10-18 02:01:02 +02:00
It also includes the OpenGL header from your development environment and
defines all the constants and types necessary for it to work on your platform.
2013-02-28 21:15:04 +01:00
2013-03-12 15:33:05 +01:00
For example, under Windows you are normally required to include `windows.h`
2015-10-18 02:01:02 +02:00
before including `GL/gl.h`. This would pollute your program's namespace with
the whole Win32 API.
2013-02-28 21:15:04 +01:00
2015-10-18 02:01:02 +02:00
Instead, the GLFW header duplicates only the very few necessary parts of it. It
does this only when needed, so if `windows.h` _is_ included, the GLFW header
2013-02-28 21:15:04 +01:00
does not try to redefine those symbols.
In other words:
2014-10-02 17:35:10 +02:00
- Do _not_ include the OpenGL headers yourself, as GLFW does this for you
- Do _not_ include `windows.h` or other platform-specific headers unless
2013-03-12 15:33:05 +01:00
you plan on using those APIs directly
2014-10-02 17:35:10 +02:00
- If you _do_ need to include such headers, do it _before_ including the
2013-05-19 10:24:14 +02:00
GLFW one and it will detect this
2015-10-18 02:05:02 +02:00
If you are using an [extension loader library](@ref context_glext_auto) to
access modern OpenGL then include the header for that library _before_ the GLFW
header. This lets it replace the OpenGL header included by GLFW without
conflicts. The following example uses [glad](https://github.com/Dav1dde/glad),
but the same rule applies to all.
@code
#include <glad/glad.h>
#include <GLFW/glfw3.h>
@endcode
2014-09-18 15:03:29 +02:00
@subsection quick_init_term Initializing and terminating GLFW
2014-09-18 15:03:29 +02:00
Before you can use most GLFW functions, the library must be initialized. On
2015-08-23 19:30:04 +02:00
successful initialization, `GLFW_TRUE` is returned. If an error occurred,
`GLFW_FALSE` is returned.
@code
if (!glfwInit())
exit(EXIT_FAILURE);
@endcode
Note that `GLFW_TRUE` and `GLFW_FALSE` are and will always be just one and zero.
2014-09-18 15:03:29 +02:00
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
2014-09-18 15:03:29 +02:00
GLFW. After this call, you must initialize GLFW again before using any GLFW
functions that require it.
2014-09-18 15:03:29 +02:00
@subsection quick_capture_error Setting an error callback
2013-02-28 21:15:04 +01:00
Most events are reported through callbacks, whether it's a key being pressed,
a GLFW window being moved, or an error occurring. Callbacks are simply
C functions (or C++ static methods) that are called by GLFW with arguments
describing the event.
2014-09-18 15:03:29 +02:00
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. This simple error callback just prints the error
2013-03-12 15:33:05 +01:00
description to `stderr`.
2013-02-28 21:15:04 +01:00
@code
void error_callback(int error, const char* description)
{
fputs(description, stderr);
}
@endcode
2014-09-18 15:03:29 +02:00
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.
2013-02-28 21:15:04 +01:00
@code
glfwSetErrorCallback(error_callback);
@endcode
2014-09-18 15:03:29 +02:00
@subsection quick_create_window Creating a window and context
2014-09-18 15:03:29 +02:00
The window and its OpenGL context are created with a single call, which returns
a handle to the created combined window and context object. For example, this
creates a 640 by 480 windowed mode window with an OpenGL context:
@code
GLFWwindow* window = glfwCreateWindow(640, 480, "My Title", NULL, NULL);
@endcode
2014-09-18 15:03:29 +02:00
If window or context creation fails, `NULL` will be returned, so it is necessary
to check the return value.
@code
if (!window)
{
glfwTerminate();
exit(EXIT_FAILURE);
}
@endcode
2014-09-18 15:03:29 +02:00
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.
2014-09-18 15:03:29 +02:00
When a window 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.
2014-09-18 15:03:29 +02:00
@subsection quick_context_current Making the OpenGL context current
2015-01-11 18:25:54 +01:00
Before you can use the OpenGL API, you must have a current OpenGL context.
@code
glfwMakeContextCurrent(window);
@endcode
2015-01-11 18:25:54 +01:00
The context will remain current until you make another context current or until
the window owning the current context is destroyed.
2014-09-18 15:03:29 +02:00
2015-10-18 02:05:02 +02:00
If you are using an [extension loader library](@ref context_glext_auto) to
access modern OpenGL then this is when to initialize it. The loader needs the
context to be current before it can load from it. The following example uses
[glad](https://github.com/Dav1dde/glad), but the same rule applies to all.
@code
gladLoadGLLoader((GLADloadproc) glfwGetProcAddress);
@endcode
2014-09-18 15:03:29 +02:00
@subsection quick_window_close Checking the window close flag
2014-09-18 15:03:29 +02:00
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.
2014-10-02 17:35:10 +02:00
Note that __the window isn't actually closed__, so you are expected to monitor
2013-03-12 15:33:05 +01:00
this flag and either destroy the window or give some kind of feedback to the
user.
@code
while (!glfwWindowShouldClose(window))
{
// Keep running
}
@endcode
2015-01-03 12:59:14 +01:00
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.
2014-09-18 15:03:29 +02:00
@subsection quick_key_input Receiving input events
2013-06-05 21:55:21 +02:00
Each window has a large number of callbacks that can be set to receive all the
2014-09-18 15:03:29 +02:00
various kinds of events. To receive key press and release events, create a key
callback function.
2013-06-05 21:55:21 +02:00
@code
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
2015-08-23 19:30:04 +02:00
glfwSetWindowShouldClose(window, GLFW_TRUE);
2013-06-05 21:55:21 +02:00
}
@endcode
2014-09-18 15:03:29 +02:00
The key callback, like other window related callbacks, are set per-window.
2013-06-05 21:55:21 +02:00
2014-09-18 15:03:29 +02:00
@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.
2013-06-05 21:55:21 +02:00
2014-09-18 15:03:29 +02:00
@subsection quick_render Rendering with OpenGL
2013-02-28 21:15:04 +01:00
Once you have a current OpenGL context, you can use OpenGL normally. In this
2013-06-05 21:26:40 +02:00
tutorial, a multi-colored rotating triangle will be rendered. The framebuffer
2014-09-18 15:03:29 +02:00
size needs to be retrieved for `glViewport`.
2013-02-28 21:15:04 +01:00
@code
2013-06-05 21:26:40 +02:00
int width, height;
glfwGetFramebufferSize(window, &width, &height);
glViewport(0, 0, width, height);
@endcode
2014-09-18 15:03:29 +02:00
You can also set a framebuffer size callback using @ref
2013-06-05 21:26:40 +02:00
glfwSetFramebufferSizeCallback and call `glViewport` from there.
2015-10-18 02:39:36 +02:00
Actual rendering with OpenGL is outside the scope of this tutorial, but there
are [many](https://open.gl/) [excellent](http://learnopengl.com/)
[tutorial](http://openglbook.com/) [sites](http://ogldev.atspace.co.uk/) that
teach modern OpenGL. Some of them use GLFW to create the context and window
while others use GLUT or SDL, but remember that OpenGL itself always works the
same.
2013-02-28 21:15:04 +01:00
2014-09-18 15:03:29 +02:00
@subsection quick_timer Reading the timer
2013-02-28 21:15:04 +01:00
2014-09-18 15:03:29 +02:00
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.
2013-02-28 21:15:04 +01:00
@code
double time = glfwGetTime();
@endcode
2014-09-18 15:03:29 +02:00
@subsection quick_swap_buffers Swapping buffers
2014-09-18 15:03:29 +02:00
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.
2014-09-18 15:03:29 +02:00
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
2014-09-18 15:03:29 +02:00
The swap interval indicates how many frames to wait until swapping the buffers,
2014-10-02 17:35:10 +02:00
commonly known as _vsync_. By default, the swap interval is zero, meaning
2014-09-18 15:03:29 +02:00
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.
2014-09-18 15:03:29 +02:00
Also, because the buffers will be swapped in the middle the screen update,
leading to [screen tearing](https://en.wikipedia.org/wiki/Screen_tearing).
2014-09-18 15:03:29 +02:00
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
2014-09-18 15:03:29 +02:00
glfwSwapInterval(1);
@endcode
2014-09-18 15:03:29 +02:00
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
2014-09-18 15:03:29 +02:00
glfwPollEvents();
@endcode
2014-09-18 15:03:29 +02:00
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.
2014-09-18 15:03:29 +02:00
@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 simple program.
2013-02-28 21:15:04 +01:00
@snippet simple.c code
2014-04-23 13:30:11 +02:00
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.
2014-04-23 13:30:11 +02:00
This program uses 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
- @ref window
- @ref context
- @ref monitor
- @ref input
@section quick_build Compiling and linking the program
The complete program above can be found in the source distribution as
`examples/simple.c` and is compiled along with all other examples when you
build GLFW. That is, if you have compiled GLFW then you have already built this
as `simple.exe` on Windows, `simple` on Linux or `simple.app` on OS X.
This 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
2013-09-24 22:17:35 +02:00
@ref build.
*/