context.dox 12 KB

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