2013-02-25 14:09:57 +01:00
|
|
|
/*!
|
|
|
|
|
|
|
|
@page quick Getting started
|
|
|
|
|
2013-03-12 18:57:38 +01:00
|
|
|
@tableofcontents
|
2013-02-25 14:09:57 +01:00
|
|
|
|
2013-03-12 18:57:38 +01:00
|
|
|
This guide will show how to write simple OpenGL applications using GLFW 3. It
|
|
|
|
will introduce a few of the most commonly used functions, but there are many
|
|
|
|
others. To see detailed documentation on any GLFW function, just click on its
|
|
|
|
name.
|
2013-02-25 14:09:57 +01:00
|
|
|
|
2013-03-29 14:06:23 +01:00
|
|
|
This guide assumes no experience with earlier versions of GLFW. If you
|
|
|
|
have used GLFW 2.x in the past, you should also read the
|
|
|
|
[transition guide](@ref moving).
|
|
|
|
|
2013-02-25 14:09:57 +01:00
|
|
|
|
|
|
|
@section quick_include Including the GLFW header
|
|
|
|
|
2013-02-28 21:15:04 +01:00
|
|
|
In the files of your program where you use OpenGL or GLFW, you need to include
|
|
|
|
the GLFW 3 header file.
|
2013-02-25 14:09:57 +01:00
|
|
|
|
|
|
|
@code
|
|
|
|
#include <GL/glfw3.h>
|
|
|
|
@endcode
|
|
|
|
|
2013-02-28 21:15:04 +01:00
|
|
|
This defines all the constants, types and function prototypes of the GLFW API.
|
|
|
|
It also includes the OpenGL header, and defines all the constants and types
|
|
|
|
necessary for it to work on your platform.
|
|
|
|
|
2013-03-12 15:33:05 +01:00
|
|
|
For example, under Windows you are normally required to include `windows.h`
|
|
|
|
before including `GL/gl.h`. This would make your source file tied to Windows
|
2013-02-28 21:15:04 +01:00
|
|
|
and pollute your code's namespace with the whole Win32 API.
|
|
|
|
|
2013-03-12 15:33:05 +01:00
|
|
|
Instead, the GLFW header takes care of this for you, not by including
|
|
|
|
`windows.h`, but rather by itself duplicating only the necessary parts of it.
|
|
|
|
It does this only where 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:
|
|
|
|
|
2013-04-07 13:46:38 +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
|
2013-04-07 13:46:38 +02:00
|
|
|
- If you *do* need to include such headers, do it *before* including the
|
2013-03-12 15:33:05 +01:00
|
|
|
GLFW and it will detect this
|
2013-02-25 14:09:57 +01:00
|
|
|
|
2013-03-12 15:33:05 +01:00
|
|
|
Starting with version 3.0, the GLU header `glu.h` is no longer included by
|
|
|
|
default. If you wish to include it, define `GLFW_INCLUDE_GLU` before the
|
2013-02-25 14:09:57 +01:00
|
|
|
inclusion of the GLFW header.
|
|
|
|
|
2013-02-28 21:15:04 +01:00
|
|
|
@code
|
|
|
|
#define GLFW_INCLUDE_GLU
|
|
|
|
#include <GL/glfw3.h>
|
|
|
|
@endcode
|
|
|
|
|
2013-02-25 14:09:57 +01:00
|
|
|
|
|
|
|
@section quick_init_term Initializing and terminating GLFW
|
|
|
|
|
|
|
|
Before you can use most GLFW functions, the library must be initialized. This
|
|
|
|
is done with @ref glfwInit, which returns non-zero if successful, or zero if an
|
|
|
|
error occurred.
|
|
|
|
|
|
|
|
@code
|
|
|
|
if (!glfwInit())
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
@endcode
|
|
|
|
|
|
|
|
When you are done using GLFW, typically at the very end of the program, you need
|
|
|
|
to call @ref glfwTerminate.
|
|
|
|
|
|
|
|
@code
|
|
|
|
glfwTerminate();
|
|
|
|
@endcode
|
|
|
|
|
|
|
|
This destroys any remaining windows and releases any other resources allocated by
|
|
|
|
GLFW. After this call, you must call @ref glfwInit again before using any GLFW
|
|
|
|
functions that require it.
|
|
|
|
|
|
|
|
|
2013-02-28 21:15:04 +01:00
|
|
|
@section 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 simply
|
|
|
|
C functions (or C++ static methods) that are called by GLFW with arguments
|
|
|
|
describing the event.
|
|
|
|
|
|
|
|
In case @ref glfwInit or any other GLFW function fails, an error is reported to
|
|
|
|
the GLFW error callback. You can receive these reports by setting the error
|
|
|
|
callback. The callback function itself should match the signature of @ref
|
|
|
|
GLFWerrorfun. Here is a simple error callback that 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
|
|
|
|
|
|
|
|
Setting the callback, so GLFW knows to call it, is done with @ref
|
|
|
|
glfwSetErrorCallback. This is one of the few GLFW functions that may be called
|
|
|
|
before @ref glfwInit, which lets you be notified of errors during
|
|
|
|
initialization, so you should set it before you do anything else with GLFW.
|
|
|
|
|
|
|
|
@code
|
|
|
|
glfwSetErrorCallback(error_callback);
|
|
|
|
@endcode
|
|
|
|
|
|
|
|
|
2013-02-25 14:09:57 +01:00
|
|
|
@section quick_create_window Creating a window and context
|
|
|
|
|
|
|
|
The window (and its context) is created with @ref glfwCreateWindow, which
|
|
|
|
returns a handle to the created window. For example, this creates an 640 by 480
|
|
|
|
pixels windowed mode window:
|
|
|
|
|
|
|
|
@code
|
|
|
|
GLFWwindow* window = glfwCreateWindow(640, 480, "My Title", NULL, NULL);
|
|
|
|
@endcode
|
|
|
|
|
2013-03-12 15:33:05 +01:00
|
|
|
If window creation fails, `NULL` will be returned, so you need to check whether
|
2013-02-25 14:09:57 +01:00
|
|
|
it did.
|
|
|
|
|
|
|
|
@code
|
|
|
|
if (!window)
|
|
|
|
{
|
|
|
|
glfwTerminate();
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
@endcode
|
|
|
|
|
|
|
|
This handle is then passed to all window related functions, and is provided to
|
|
|
|
you along with input events, so you know which window received the input.
|
|
|
|
|
|
|
|
To create a fullscreen window, you need to specify which monitor the window
|
|
|
|
should use. In most cases, the user's primary monitor is a good choice. You
|
|
|
|
can get this with @ref glfwGetPrimaryMonitor. To make the above window
|
|
|
|
fullscreen, just pass along the monitor handle:
|
|
|
|
|
|
|
|
@code
|
|
|
|
GLFWwindow* window = glfwCreateWindow(640, 480, "My Title", glfwGetPrimaryMonitor(), NULL);
|
|
|
|
@endcode
|
|
|
|
|
|
|
|
Fullscreen windows cover the entire screen, have no border or decorations, and
|
|
|
|
change the monitor's resolution to the one most closely matching the requested
|
|
|
|
window size.
|
|
|
|
|
|
|
|
When you are done with the window, destroy it with the @ref glfwDestroyWindow
|
|
|
|
function.
|
|
|
|
|
|
|
|
@code
|
|
|
|
glfwDestroyWindow(window);
|
|
|
|
@endcode
|
|
|
|
|
|
|
|
Once this function is called, no more events will be delivered for that window
|
|
|
|
and its handle becomes invalid.
|
|
|
|
|
|
|
|
|
2013-02-25 15:49:58 +01:00
|
|
|
@section quick_context_current Making the OpenGL context current
|
|
|
|
|
|
|
|
Before you can use the OpenGL API, it must have a current OpenGL context. You
|
|
|
|
make a window's context current with @ref glfwMakeContextCurrent. It will then
|
|
|
|
remain as the current context until you make another context current or until
|
|
|
|
the window owning it is destroyed.
|
|
|
|
|
|
|
|
@code
|
|
|
|
glfwMakeContextCurrent(window);
|
|
|
|
@endcode
|
|
|
|
|
|
|
|
|
2013-03-01 13:45:12 +01:00
|
|
|
@section quick_window_params Checking the window close flag
|
2013-02-25 14:09:57 +01:00
|
|
|
|
2013-03-01 13:45:12 +01:00
|
|
|
Each window has a flag indicating whether the window should be closed. This can
|
|
|
|
be checked with @ref glfwWindowShouldClose.
|
|
|
|
|
|
|
|
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.
|
2013-03-12 15:33:05 +01:00
|
|
|
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.
|
2013-02-25 14:09:57 +01:00
|
|
|
|
|
|
|
@code
|
2013-03-01 13:45:12 +01:00
|
|
|
while (!glfwWindowShouldClose(window))
|
2013-02-25 14:09:57 +01:00
|
|
|
{
|
|
|
|
// Keep running
|
|
|
|
}
|
|
|
|
@endcode
|
|
|
|
|
2013-03-06 23:29:37 +01:00
|
|
|
You can be notified when 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.
|
2013-03-01 13:45:12 +01:00
|
|
|
|
|
|
|
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.
|
|
|
|
|
2013-02-25 14:09:57 +01:00
|
|
|
|
2013-02-28 21:15:04 +01:00
|
|
|
@section 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 window size,
|
2013-03-12 15:33:05 +01:00
|
|
|
needed here by `glViewport` and `glOrtho`, is retrieved using @ref
|
2013-02-28 21:15:04 +01:00
|
|
|
glfwGetWindowSize. However, if you only need it for updating the viewport when
|
|
|
|
the window size changes, you can set a window size callback using @ref
|
2013-03-12 15:33:05 +01:00
|
|
|
glfwSetWindowSizeCallback and call `glViewport` from there.
|
2013-02-28 21:15:04 +01:00
|
|
|
|
|
|
|
@code
|
|
|
|
void window_size_callback(GLFWwindow* window, int width, int height)
|
|
|
|
{
|
|
|
|
glViewport(0, 0, width, height);
|
|
|
|
}
|
|
|
|
@endcode
|
|
|
|
|
|
|
|
|
|
|
|
@section quick_timer Reading the timer
|
|
|
|
|
|
|
|
For the triangle to rotate properly, a time source is needed. GLFW provides
|
|
|
|
@ref glfwGetTime, which returns the number of seconds since @ref glfwInit as
|
2013-03-12 15:33:05 +01:00
|
|
|
a `double`. The time source used is the most accurate on each platform and
|
2013-02-28 21:15:04 +01:00
|
|
|
generally has micro- or nanosecond resolution.
|
|
|
|
|
|
|
|
@code
|
|
|
|
double time = glfwGetTime();
|
|
|
|
@endcode
|
|
|
|
|
|
|
|
|
2013-02-25 14:09:57 +01:00
|
|
|
@section quick_swap_buffers Swapping buffers
|
|
|
|
|
|
|
|
GLFW windows always use double-buffering. That means that you have 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, it is time to swap the back and the
|
|
|
|
front buffers in order to display the rendered frame, and begin rendering a new
|
|
|
|
frame. This is done with @ref glfwSwapBuffers.
|
|
|
|
|
|
|
|
@code
|
|
|
|
glfwSwapBuffers(window);
|
|
|
|
@endcode
|
|
|
|
|
|
|
|
|
|
|
|
@section quick_process_events Processing events
|
|
|
|
|
2013-02-28 21:15:04 +01:00
|
|
|
GLFW needs to communicate regularly with the window system both in order to
|
|
|
|
receive events and to show that it hasn't locked up. Event processing must be
|
|
|
|
done regularly and is normally done each frame before rendering but after buffer
|
|
|
|
swap.
|
2013-02-25 14:09:57 +01:00
|
|
|
|
2013-02-28 21:15:04 +01:00
|
|
|
There are two ways to process pending events. @ref glfwPollEvents processes
|
|
|
|
only those events that have already been received and then returns immediately.
|
|
|
|
This is the best choice when rendering continually, like most games do.
|
2013-02-25 14:09:57 +01:00
|
|
|
|
|
|
|
@code
|
|
|
|
glfwPollEvents();
|
|
|
|
@endcode
|
|
|
|
|
|
|
|
If instead you only need to update your rendering once you have received new
|
2013-02-28 21:15:04 +01:00
|
|
|
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 just like @ref glfwPollEvents does. This saves
|
|
|
|
a great deal of CPU cycles and is useful for, for example, many kinds of editing
|
|
|
|
tools.
|
2013-02-25 14:09:57 +01:00
|
|
|
|
|
|
|
@code
|
|
|
|
glfwWaitEvents();
|
|
|
|
@endcode
|
|
|
|
|
|
|
|
|
2013-02-28 21:15:04 +01:00
|
|
|
@section quick_example Putting it together: A small GLFW application
|
2013-02-25 14:09:57 +01:00
|
|
|
|
|
|
|
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
|
2013-02-25 14:09:57 +01:00
|
|
|
|
|
|
|
This program creates a 640 by 480 pixels window and runs a loop clearing the
|
2013-02-28 21:15:04 +01:00
|
|
|
screen, rendering a triangle and processing events until the user closes the
|
2013-03-18 15:57:58 +01:00
|
|
|
window. It can be found in the source distribution as `examples/simple.c`, and
|
|
|
|
is by default compiled along with all other examples when you build GLFW.
|
2013-02-25 14:09:57 +01:00
|
|
|
|
|
|
|
*/
|