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