/*! @page context Context handling guide @tableofcontents The primary purpose of GLFW is to provide a simple interface to window management and OpenGL and OpenGL ES context creation. GLFW supports multiple windows, with each window having its own context. @section context_object Context handles The @ref GLFWwindow object encapsulates both a [window](@ref window) and a context. It is created with @ref glfwCreateWindow and destroyed with @ref glfwDestroyWindow or @ref glfwTerminate. As the window and context are inseparably linked, the object pointer is used as both a context and window handle. @section context_hints Context creation hints There are a number of hints, specified using @ref glfwWindowHint, related to what kind of context is created. See [context related hints](@ref window_hints_ctx) in the window handling guide. @section context_sharing Context object sharing When creating a window and context with @ref glfwCreateWindow, you can specify another window whose context the new one should share its objects with. Object sharing is implemented by the operating system and graphics driver and is described in the OpenGL and OpenGL ES documentation. On platforms where it is possible to choose which types of objects are shared, GLFW requests that all are shared. @section context_current Current context Before you can make OpenGL or OpenGL ES calls, you need to have a current context of the proper type. The context encapsulates all render state and all objects like textures and shaders. A context is made current with @ref glfwMakeContextCurrent. @code glfwMakeContextCurrent(window); @endcode The current context is returned by @ref glfwGetCurrentContext. @code GLFWwindow* window = glfwGetCurrentContext(); @endcode @note A context must only be current for a single thread at a time, and a thread must only have a single context current at a time. @section context_swap Swapping buffers Buffer swapping is part of the window and framebuffer, not the context. See @ref window_swap in the window handling guide. @section context_glext OpenGL and OpenGL ES extensions One of the benefits of OpenGL and OpenGL ES are their extensibility. Hardware vendors may include extensions in their implementations that extend the API before that functionality is included in a new version of the OpenGL or OpenGL ES specification, and some extensions are never included and remain as extensions until they become obsolete. An extension is defined by: - An extension name (e.g. `GL_ARB_debug_output`) - New OpenGL tokens (e.g. `GL_DEBUG_SEVERITY_HIGH_ARB`) - New OpenGL functions (e.g. `glGetDebugMessageLogARB`) Note the `ARB` affix, which stands for Architecture Review Board and is used for official extensions. The extension above was created by the ARB, but there are many different affixes, like `NV` for Nvidia and `AMD` for, well, AMD. Any group may also use the generic `EXT` affix. Lists of extensions, together with their specifications, can be found at the [OpenGL Registry](http://www.opengl.org/registry/) and [OpenGL ES Registry](https://www.khronos.org/registry/gles/). @subsection context_glext_auto Using an extension loader library This is the easiest and best way to load extensions and newer versions of the OpenGL or OpenGL ES API. One such library is [glad](https://github.com/Dav1dde/glad) and there are several others. They will take care of all the details of declaring and loading everything you need. The following example will use glad, but other extension loader libraries work similary. First you need to generate the source files using the glad Python script. This example generates a loader for any version of OpenGL, which is the default for both GLFW and glad, but loaders for OpenGL ES, as well as loaders for specific API versions and extension sets can be generated. The generated files are written to the `output` directory. @code{.sh} python main.py --no-loader --out-path output @endcode @note The `--no-loader` option is used because GLFW already provides a function for loading OpenGL and OpenGL ES function pointers and glad can use this instead of having to add its own. Add the generated `output/src/glad.c`, `output/include/glad/glad.h` and `output/include/KHR/khrplatform.h` files to your build. Then you need to include the glad header file, which will replace the OpenGL header of your development environment. @code #include #include @endcode Finally you need to initialize glad once you have a matching current context. @code window = glfwCreateWindow(640, 480, "My Window", NULL, NULL); if (!window) { ... } glfwMakeContextCurrent(window); gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); @endcode Once glad has been loaded, you have access to all OpenGL core and extension functions supported by the context you created and you are ready to start rendering. You can specify a minimum required OpenGL or OpenGL ES version with [context hints](@ref window_hints_ctx). If your needs are more complex, you can check the actual OpenGL or OpenGL ES version with [context attributes](@ref window_attribs_context), or you can check whether a specific version is supported by the current context with the `GLAD_GL_VERSION_x_x` booleans. @code if (GLAD_GL_VERSION_3_2) { // Call OpenGL 3.2+ specific code } @endcode To check whether a specific extension is supported, use the `GLAD_GL_xxx` booleans. @code if (GLAD_GL_ARB_debug_output) { // Use GL_ARB_debug_output } @endcode @subsection context_glext_manual Loading extensions manually To use a certain extension, you must first check whether the context supports that extension and then, if it introduces new functions, retrieve the pointers to those functions. GLFW provides @ref glfwExtensionSupported and @ref glfwGetProcAddress for manual loading of extensions and new API functions. @note It is strongly recommended that you use an existing extension loader library like [glad](https://github.com/Dav1dde/glad) instead of loading manually. Extension loading is a solved problem and you will gain nothing from solving it again by hand. @subsubsection context_glext_header The glext.h header The `glext.h` header is a continually updated file that defines the interfaces for all OpenGL extensions. The latest version of this can always be found at the [OpenGL Registry](http://www.opengl.org/registry/). It it strongly recommended that you use your own copy, as the one shipped with your development environment may be several years out of date and may not include the extensions you wish to use. The header defines function pointer types for all functions of all extensions it supports. These have names like `PFNGLGETDEBUGMESSAGELOGARB` (for `glGetDebugMessageLogARB`), i.e. the name is made uppercase and `PFN` (pointer to function) and `PROC` (procedure) are added to the ends. @subsubsection context_glext_string Checking for extensions A given machine may not actually support the extension (it may have older drivers or a graphics card that lacks the necessary hardware features), so it is necessary to check whether the context supports the extension. This is done with @ref glfwExtensionSupported. @code if (glfwExtensionSupported("GL_ARB_debug_output")) { // The extension is supported by the current context } @endcode The argument is a null terminated ASCII string with the extension name. If the extension is supported, @ref glfwExtensionSupported returns non-zero, otherwise it returns zero. @subsubsection context_glext_proc Fetching function pointers Many extensions, though not all, require the use of new OpenGL functions. These functions often do not have entry points in the client API libraries of your operating system, making it necessary to fetch them at run time. You can retreive pointers to these functions with @ref glfwGetProcAddress. @code PFNGLGETDEBUGMESSAGELOGARB pfnGetDebugMessageLog = glfwGetProcAddress("glGetDebugMessageLogARB"); @endcode In general, you should avoid giving the function pointer variables the (exact) same name as the function, as this may confuse your linker. Instead, you can use a different prefix, like above, or some other naming scheme. Now that all the pieces have been introduced, here is what they might look like when used together. @code #include "glext.h" #define glGetDebugMessageLogARB pfnGetDebugMessageLog PFNGLGETDEBUGMESSAGELOGARB pfnGetDebugMessageLog; // Flag indicating whether the extension is supported int has_debug_output = 0; void load_extensions(void) { if (glfwExtensionSupported("GL_ARB_debug_output")) { pfnGetDebugMessageLog = (PFNGLGETDEBUGMESSAGELOGARB) glfwGetProcAddress("glGetDebugMessageLogARB"); if (pfnGetDebugMessageLog) { // Both the extension name and the function pointer are present has_debug_output = 1; } } } void some_function(void) { // Now the extension function can be called as usual glGetDebugMessageLogARB(...); } @endcode */