329 lines
11 KiB
Plaintext
329 lines
11 KiB
Plaintext
|
/*!
|
||
|
|
||
|
@page quick Getting started
|
||
|
|
||
|
@tableofcontents
|
||
|
|
||
|
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.
|
||
|
|
||
|
This guide assumes no experience with earlier versions of GLFW. If you
|
||
|
have used GLFW 2 in the past, read the @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 OpenGL or GLFW, you need
|
||
|
to include the GLFW 3 header file.
|
||
|
|
||
|
@code
|
||
|
#include <GLFW/glfw3.h>
|
||
|
@endcode
|
||
|
|
||
|
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.
|
||
|
|
||
|
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
|
||
|
and pollute your code's namespace with the whole Win32 API.
|
||
|
|
||
|
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
|
||
|
does not try to redefine those symbols.
|
||
|
|
||
|
In other words:
|
||
|
|
||
|
- Do _not_ include the OpenGL headers yourself, as GLFW does this for you
|
||
|
- Do _not_ include `windows.h` or other platform-specific headers unless
|
||
|
you plan on using those APIs directly
|
||
|
- If you _do_ need to include such headers, do it _before_ including the
|
||
|
GLFW one and it will detect this
|
||
|
|
||
|
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
|
||
|
inclusion of the GLFW header.
|
||
|
|
||
|
@code
|
||
|
#define GLFW_INCLUDE_GLU
|
||
|
#include <GLFW/glfw3.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, `GL_TRUE` is returned. If an error occurred,
|
||
|
`GL_FALSE` is returned.
|
||
|
|
||
|
@code
|
||
|
if (!glfwInit())
|
||
|
exit(EXIT_FAILURE);
|
||
|
@endcode
|
||
|
|
||
|
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 simply
|
||
|
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. This simple error callback just prints the error
|
||
|
description to `stderr`.
|
||
|
|
||
|
@code
|
||
|
void error_callback(int error, const char* description)
|
||
|
{
|
||
|
fputs(description, stderr);
|
||
|
}
|
||
|
@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, 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
|
||
|
|
||
|
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
|
||
|
|
||
|
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 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.
|
||
|
|
||
|
|
||
|
@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, GL_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 call `glViewport` from there.
|
||
|
|
||
|
|
||
|
@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 simple program.
|
||
|
|
||
|
@snippet simple.c code
|
||
|
|
||
|
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.
|
||
|
|
||
|
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
|
||
|
@ref build.
|
||
|
|
||
|
*/
|