| /*! |
| |
| @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, each of which has its own context. |
| |
| |
| @section context_object Context handles |
| |
| The @ref GLFWwindow object encapsulates both a window and a context. They are |
| created with @ref glfwCreateWindow and destroyed with @ref glfwDestroyWindow (or |
| @ref glfwTerminate, if any remain). 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. OpenGL |
| object sharing is implemented by the operating system and graphics driver and is |
| described in the OpenGL 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 use the OpenGL or OpenGL ES APIs, you need to have a current |
| context of the proper type. The context encapsulates all render state and all |
| objects like textures and shaders. |
| |
| Note that a context can only be current for a single thread at a time, and |
| a thread can only have a single context at a time. |
| |
| 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 |
| |
| |
| @section context_swap Swapping buffers |
| |
| See [swapping buffers](@ref window_swap) in the window handling guide. |
| |
| |
| @section context_glext OpenGL extension handling |
| |
| One of the benefits of OpenGL is its extensibility. Independent hardware |
| vendors (IHVs) may include functionality in their OpenGL implementations that |
| expand upon the OpenGL standard before that functionality is included in a new |
| version of the OpenGL specification. |
| |
| 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. There are many different affixes, depending on who |
| wrote the extension. A list of extensions, together with their specifications, |
| can be found at the [OpenGL Registry](http://www.opengl.org/registry/). |
| |
| 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. |
| |
| This can be done with GLFW, as will be described in this section, but usually |
| you will instead want to use a dedicated extension loading library such as |
| [GLEW](http://glew.sourceforge.net/). This kind of library greatly reduces the |
| amount of work necessary to use both OpenGL extensions and modern versions of |
| the OpenGL API. GLEW in particular has been extensively tested with and works |
| well with GLFW. |
| |
| |
| @subsection 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` and `PROC` |
| are added to the ends. |
| |
| |
| @subsection 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. |
| |
| |
| @subsection context_glext_proc Fetching function pointers |
| |
| Many extensions, though not all, require the use of new OpenGL functions. |
| These entry points are often not exposed by your link libraries, making |
| it necessary to fetch them at run time. With @ref glfwGetProcAddress you can |
| retrieve the address of extension and non-extension OpenGL functions. |
| |
| @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 |
| |
| */ |