You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
275 lines
9.0 KiB
275 lines
9.0 KiB
/*! |
|
|
|
@page quick Getting started |
|
|
|
@section quick_start Introduction |
|
|
|
In this guide you will learn how to write simple OpenGL applications using |
|
GLFW 3. It will introduce you to 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. |
|
|
|
|
|
@section quick_include Including the GLFW header |
|
|
|
In the files of your program where you use OpenGL or GLFW, you need to include |
|
the GLFW 3 header file. |
|
|
|
@code |
|
#include <GL/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 @c windows.h |
|
before including @c 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 @c |
|
windows.h, but rather by itself duplicating only the necessary parts of it. It |
|
does this only where needed, so if @c windows.h @em is included, the GLFW header |
|
does not try to redefine those symbols. |
|
|
|
In other words: |
|
|
|
@arg Do @em not include the OpenGL headers yourself, as GLFW does this for you |
|
@arg Do @em not include @c windows.h or other platform-specific headers unless |
|
you plan on using those APIs directly |
|
@arg If you @em do need to include such headers, do it @em before including the |
|
GLFW and it will detect this |
|
|
|
Starting with version 3.0, the GLU header @c glu.h is no longer included by |
|
default. If you wish to include it, define @c GLFW_INCLUDE_GLU before the |
|
inclusion of the GLFW header. |
|
|
|
@code |
|
#define GLFW_INCLUDE_GLU |
|
#include <GL/glfw3.h> |
|
@endcode |
|
|
|
|
|
@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. |
|
|
|
|
|
@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 |
|
description to @c stderr. |
|
|
|
@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 |
|
|
|
|
|
@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 |
|
|
|
If window creation fails, @c NULL will be returned, so you need to check whether |
|
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. |
|
|
|
|
|
@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 |
|
|
|
|
|
@section quick_window_params Checking the window close flag |
|
|
|
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. |
|
Note that <b>the window isn't actually closed</b>, 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 intercept the setting of the close flag by setting a close callback with |
|
@ref glfwSetWindowCloseCallback. The return value of the close callback becomes |
|
the new value of the close flag. |
|
|
|
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. |
|
|
|
|
|
@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, |
|
needed here by @c glViewport and @c glOrtho, is retrieved using @ref |
|
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 |
|
glfwSetWindowSizeCallback and call @c glViewport from there. |
|
|
|
@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 |
|
a @c double. The time source used is the most accurate on each platform and |
|
generally has micro- or nanosecond resolution. |
|
|
|
@code |
|
double time = glfwGetTime(); |
|
@endcode |
|
|
|
|
|
@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 |
|
|
|
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. |
|
|
|
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. |
|
|
|
@code |
|
glfwPollEvents(); |
|
@endcode |
|
|
|
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 just like @ref glfwPollEvents does. This saves |
|
a great deal of CPU cycles and is useful for, for example, many kinds of editing |
|
tools. |
|
|
|
@code |
|
glfwWaitEvents(); |
|
@endcode |
|
|
|
|
|
@section quick_example Putting it together: A small GLFW application |
|
|
|
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 pixels window and runs a loop clearing the |
|
screen, rendering a triangle and processing events until the user closes the |
|
window. |
|
|
|
*/
|
|
|