• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*!
2
3@page context_guide Context guide
4
5@tableofcontents
6
7This guide introduces the OpenGL and OpenGL ES context related functions of
8GLFW.  For details on a specific function in this category, see the @ref
9context.  There are also guides for the other areas of the GLFW API.
10
11 - @ref intro_guide
12 - @ref window_guide
13 - @ref vulkan_guide
14 - @ref monitor_guide
15 - @ref input_guide
16
17
18@section context_object Context objects
19
20A window object encapsulates both a top-level window and an OpenGL or OpenGL ES
21context.  It is created with @ref glfwCreateWindow and destroyed with @ref
22glfwDestroyWindow or @ref glfwTerminate.  See @ref window_creation for more
23information.
24
25As the window and context are inseparably linked, the window object also serves
26as the context handle.
27
28To test the creation of various kinds of contexts and see their properties, run
29the `glfwinfo` test program.
30
31@note Vulkan does not have a context and the Vulkan instance is created via the
32Vulkan API itself.  If you will be using Vulkan to render to a window, disable
33context creation by setting the [GLFW_CLIENT_API](@ref window_hints_ctx) hint to
34`GLFW_NO_API`.  For more information, see the @ref vulkan_guide.
35
36
37@subsection context_hints Context creation hints
38
39There are a number of hints, specified using @ref glfwWindowHint, related to
40what kind of context is created.  See
41[context related hints](@ref window_hints_ctx) in the window guide.
42
43
44@subsection context_sharing Context object sharing
45
46When creating a window and its OpenGL or OpenGL ES context with @ref
47glfwCreateWindow, you can specify another window whose context the new one
48should share its objects (textures, vertex and element buffers, etc.) with.
49
50@code
51GLFWwindow* second_window = glfwCreateWindow(640, 480, "Second Window", NULL, first_window);
52@endcode
53
54Object sharing is implemented by the operating system and graphics driver.  On
55platforms where it is possible to choose which types of objects are shared, GLFW
56requests that all types are shared.
57
58See the relevant chapter of the [OpenGL](https://www.opengl.org/registry/) or
59[OpenGL ES](http://www.khronos.org/opengles/) reference documents for more
60information.  The name and number of this chapter unfortunately varies between
61versions and APIs, but has at times been named _Shared Objects and Multiple
62Contexts_.
63
64GLFW comes with a simple object sharing test program called `sharing`.
65
66
67@subsection context_offscreen Offscreen contexts
68
69GLFW doesn't support creating contexts without an associated window.  However,
70contexts with hidden windows can be created with the
71[GLFW_VISIBLE](@ref window_hints_wnd) window hint.
72
73@code
74glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
75
76GLFWwindow* offscreen_context = glfwCreateWindow(640, 480, "", NULL, NULL);
77@endcode
78
79The window never needs to be shown and its context can be used as a plain
80offscreen context.  Depending on the window manager, the size of a hidden
81window's framebuffer may not be usable or modifiable, so framebuffer
82objects are recommended for rendering with such contexts.
83
84You should still [process events](@ref events) as long as you have at least one
85window, even if none of them are visible.
86
87__OS X:__ The first time a window is created the menu bar is populated with
88common commands like Hide, Quit and About.  This is not desirable for example
89when writing a command-line only application.  The menu bar setup can be
90disabled with a [compile-time option](@ref compile_options_osx).
91
92
93@subsection context_less Windows without contexts
94
95You can disable context creation by setting the
96[GLFW_CLIENT_API](@ref window_hints_ctx) hint to `GLFW_NO_API`.  Windows without
97contexts must not be passed to @ref glfwMakeContextCurrent or @ref
98glfwSwapBuffers.
99
100
101@section context_current Current context
102
103Before you can make OpenGL or OpenGL ES calls, you need to have a current
104context of the correct type.  A context can only be current for a single thread
105at a time, and a thread can only have a single context current at a time.
106
107The context of a window is made current with @ref glfwMakeContextCurrent.
108
109@code
110glfwMakeContextCurrent(window);
111@endcode
112
113The window of the current context is returned by @ref glfwGetCurrentContext.
114
115@code
116GLFWwindow* window = glfwGetCurrentContext();
117@endcode
118
119The following GLFW functions require a context to be current.  Calling any these
120functions without a current context will generate a @ref GLFW_NO_CURRENT_CONTEXT
121error.
122
123 - @ref glfwSwapInterval
124 - @ref glfwExtensionSupported
125 - @ref glfwGetProcAddress
126
127
128@section context_swap Buffer swapping
129
130Buffer swapping is part of the window and framebuffer, not the context.  See
131@ref buffer_swap.
132
133
134@section context_glext OpenGL and OpenGL ES extensions
135
136One of the benefits of OpenGL and OpenGL ES is their extensibility.
137Hardware vendors may include extensions in their implementations that extend the
138API before that functionality is included in a new version of the OpenGL or
139OpenGL ES specification, and some extensions are never included and remain
140as extensions until they become obsolete.
141
142An extension is defined by:
143
144- An extension name (e.g. `GL_ARB_debug_output`)
145- New OpenGL tokens (e.g. `GL_DEBUG_SEVERITY_HIGH_ARB`)
146- New OpenGL functions (e.g. `glGetDebugMessageLogARB`)
147
148Note the `ARB` affix, which stands for Architecture Review Board and is used
149for official extensions.  The extension above was created by the ARB, but there
150are many different affixes, like `NV` for Nvidia and `AMD` for, well, AMD.  Any
151group may also use the generic `EXT` affix.  Lists of extensions, together with
152their specifications, can be found at the
153[OpenGL Registry](http://www.opengl.org/registry/) and
154[OpenGL ES Registry](https://www.khronos.org/registry/gles/).
155
156
157@subsection context_glext_auto Loading extension with a loader library
158
159An extension loader library is the easiest and best way to access both OpenGL and
160OpenGL ES extensions and modern versions of the core OpenGL or OpenGL ES APIs.
161They will take care of all the details of declaring and loading everything you
162need.  One such library is [glad](https://github.com/Dav1dde/glad) and there are
163several others.
164
165The following example will use glad but all extension loader libraries work
166similarly.
167
168First you need to generate the source files using the glad Python script.  This
169example generates a loader for any version of OpenGL, which is the default for
170both GLFW and glad, but loaders for OpenGL ES, as well as loaders for specific
171API versions and extension sets can be generated.  The generated files are
172written to the `output` directory.
173
174@code{.sh}
175python main.py --generator c --no-loader --out-path output
176@endcode
177
178The `--no-loader` option is added because GLFW already provides a function for
179loading OpenGL and OpenGL ES function pointers, one that automatically uses the
180selected context creation API, and glad can call this instead of having to
181implement its own.  There are several other command-line options as well.  See
182the glad documentation for details.
183
184Add the generated `output/src/glad.c`, `output/include/glad/glad.h` and
185`output/include/KHR/khrplatform.h` files to your build.  Then you need to
186include the glad header file, which will replace the OpenGL header of your
187development environment.  By including the glad header before the GLFW header,
188it suppresses the development environment's OpenGL or OpenGL ES header.
189
190@code
191#include <glad/glad.h>
192#include <GLFW/glfw3.h>
193@endcode
194
195Finally you need to initialize glad once you have a suitable current context.
196
197@code
198window = glfwCreateWindow(640, 480, "My Window", NULL, NULL);
199if (!window)
200{
201    ...
202}
203
204glfwMakeContextCurrent(window);
205
206gladLoadGLLoader((GLADloadproc) glfwGetProcAddress);
207@endcode
208
209Once glad has been loaded, you have access to all OpenGL core and extension
210functions supported by both the context you created and the glad loader you
211generated and you are ready to start rendering.
212
213You can specify a minimum required OpenGL or OpenGL ES version with
214[context hints](@ref window_hints_ctx).  If your needs are more complex, you can
215check the actual OpenGL or OpenGL ES version with
216[context attributes](@ref window_attribs_ctx), or you can check whether
217a specific version is supported by the current context with the
218`GLAD_GL_VERSION_x_x` booleans.
219
220@code
221if (GLAD_GL_VERSION_3_2)
222{
223    // Call OpenGL 3.2+ specific code
224}
225@endcode
226
227To check whether a specific extension is supported, use the `GLAD_GL_xxx`
228booleans.
229
230@code
231if (GLAD_GL_ARB_debug_output)
232{
233    // Use GL_ARB_debug_output
234}
235@endcode
236
237
238@subsection context_glext_manual Loading extensions manually
239
240__Do not use this technique__ unless it is absolutely necessary.  An
241[extension loader library](@ref context_glext_auto) will save you a ton of
242tedious, repetitive, error prone work.
243
244To use a certain extension, you must first check whether the context supports
245that extension and then, if it introduces new functions, retrieve the pointers
246to those functions.  GLFW provides @ref glfwExtensionSupported and @ref
247glfwGetProcAddress for manual loading of extensions and new API functions.
248
249This section will demonstrate manual loading of OpenGL extensions.  The loading
250of OpenGL ES extensions is identical except for the name of the extension header.
251
252
253@subsubsection context_glext_header The glext.h header
254
255The `glext.h` extension header is a continually updated file that defines the
256interfaces for all OpenGL extensions.  The latest version of this can always be
257found at the [OpenGL Registry](http://www.opengl.org/registry/).  There are also
258extension headers for the various versions of OpenGL ES at the
259[OpenGL ES Registry](https://www.khronos.org/registry/gles/).  It it strongly
260recommended that you use your own copy of the extension header, as the one
261included in your development environment may be several years out of date and
262may not include the extensions you wish to use.
263
264The header defines function pointer types for all functions of all extensions it
265supports.  These have names like `PFNGLGETDEBUGMESSAGELOGARBPROC` (for
266`glGetDebugMessageLogARB`), i.e. the name is made uppercase and `PFN` (pointer
267to function) and `PROC` (procedure) are added to the ends.
268
269To include the extension header, define [GLFW_INCLUDE_GLEXT](@ref build_macros)
270before including the GLFW header.
271
272@code
273#define GLFW_INCLUDE_GLEXT
274#include <GLFW/glfw3.h>
275@endcode
276
277
278@subsubsection context_glext_string Checking for extensions
279
280A given machine may not actually support the extension (it may have older
281drivers or a graphics card that lacks the necessary hardware features), so it
282is necessary to check at run-time whether the context supports the extension.
283This is done with @ref glfwExtensionSupported.
284
285@code
286if (glfwExtensionSupported("GL_ARB_debug_output"))
287{
288    // The extension is supported by the current context
289}
290@endcode
291
292The argument is a null terminated ASCII string with the extension name.  If the
293extension is supported, @ref glfwExtensionSupported returns `GLFW_TRUE`,
294otherwise it returns `GLFW_FALSE`.
295
296
297@subsubsection context_glext_proc Fetching function pointers
298
299Many extensions, though not all, require the use of new OpenGL functions.
300These functions often do not have entry points in the client API libraries of
301your operating system, making it necessary to fetch them at run time.  You can
302retrieve pointers to these functions with @ref glfwGetProcAddress.
303
304@code
305PFNGLGETDEBUGMESSAGELOGARBPROC pfnGetDebugMessageLog = glfwGetProcAddress("glGetDebugMessageLogARB");
306@endcode
307
308In general, you should avoid giving the function pointer variables the (exact)
309same name as the function, as this may confuse your linker.  Instead, you can
310use a different prefix, like above, or some other naming scheme.
311
312Now that all the pieces have been introduced, here is what they might look like
313when used together.
314
315@code
316#define GLFW_INCLUDE_GLEXT
317#include <GLFW/glfw3.h>
318
319#define glGetDebugMessageLogARB pfnGetDebugMessageLog
320PFNGLGETDEBUGMESSAGELOGARBPROC pfnGetDebugMessageLog;
321
322// Flag indicating whether the extension is supported
323int has_ARB_debug_output = 0;
324
325void load_extensions(void)
326{
327    if (glfwExtensionSupported("GL_ARB_debug_output"))
328    {
329        pfnGetDebugMessageLog = (PFNGLGETDEBUGMESSAGELOGARBPROC)
330            glfwGetProcAddress("glGetDebugMessageLogARB");
331        has_ARB_debug_output = 1;
332    }
333}
334
335void some_function(void)
336{
337    if (has_ARB_debug_output)
338    {
339        // Now the extension function can be called as usual
340        glGetDebugMessageLogARB(...);
341    }
342}
343@endcode
344
345*/
346