Platformer in OpenGL
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

345 lines
12 KiB

5 years ago
  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 window_hints_ctx) hint to
  24. `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 window_hints_wnd) 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. __OS X:__ The first time a window is created the menu bar is populated with
  60. common commands like Hide, Quit and About. This is not desirable for example
  61. when writing a command-line only application. The menu bar setup can be
  62. disabled with a [compile-time option](@ref compile_options_osx).
  63. @subsection context_less Windows without contexts
  64. You can disable context creation by setting the
  65. [GLFW_CLIENT_API](@ref window_hints_ctx) hint to `GLFW_NO_API`. Windows without
  66. contexts must not be passed to @ref glfwMakeContextCurrent or @ref
  67. glfwSwapBuffers.
  68. @section context_current Current context
  69. Before you can make OpenGL or OpenGL ES calls, you need to have a current
  70. context of the correct type. A context can only be current for a single thread
  71. at a time, and a thread can only have a single context current at a time.
  72. The context of a window is made current with @ref glfwMakeContextCurrent.
  73. @code
  74. glfwMakeContextCurrent(window);
  75. @endcode
  76. The window of the current context is returned by @ref glfwGetCurrentContext.
  77. @code
  78. GLFWwindow* window = glfwGetCurrentContext();
  79. @endcode
  80. The following GLFW functions require a context to be current. Calling any these
  81. functions without a current context will generate a @ref GLFW_NO_CURRENT_CONTEXT
  82. error.
  83. - @ref glfwSwapInterval
  84. - @ref glfwExtensionSupported
  85. - @ref glfwGetProcAddress
  86. @section context_swap Buffer swapping
  87. Buffer swapping is part of the window and framebuffer, not the context. See
  88. @ref buffer_swap.
  89. @section context_glext OpenGL and OpenGL ES extensions
  90. One of the benefits of OpenGL and OpenGL ES is their extensibility.
  91. Hardware vendors may include extensions in their implementations that extend the
  92. API before that functionality is included in a new version of the OpenGL or
  93. OpenGL ES specification, and some extensions are never included and remain
  94. as extensions until they become obsolete.
  95. An extension is defined by:
  96. - An extension name (e.g. `GL_ARB_debug_output`)
  97. - New OpenGL tokens (e.g. `GL_DEBUG_SEVERITY_HIGH_ARB`)
  98. - New OpenGL functions (e.g. `glGetDebugMessageLogARB`)
  99. Note the `ARB` affix, which stands for Architecture Review Board and is used
  100. for official extensions. The extension above was created by the ARB, but there
  101. are many different affixes, like `NV` for Nvidia and `AMD` for, well, AMD. Any
  102. group may also use the generic `EXT` affix. Lists of extensions, together with
  103. their specifications, can be found at the
  104. [OpenGL Registry](http://www.opengl.org/registry/) and
  105. [OpenGL ES Registry](https://www.khronos.org/registry/gles/).
  106. @subsection context_glext_auto Loading extension with a loader library
  107. An extension loader library is the easiest and best way to access both OpenGL and
  108. OpenGL ES extensions and modern versions of the core OpenGL or OpenGL ES APIs.
  109. They will take care of all the details of declaring and loading everything you
  110. need. One such library is [glad](https://github.com/Dav1dde/glad) and there are
  111. several others.
  112. The following example will use glad but all extension loader libraries work
  113. similarly.
  114. First you need to generate the source files using the glad Python script. This
  115. example generates a loader for any version of OpenGL, which is the default for
  116. both GLFW and glad, but loaders for OpenGL ES, as well as loaders for specific
  117. API versions and extension sets can be generated. The generated files are
  118. written to the `output` directory.
  119. @code{.sh}
  120. python main.py --generator c --no-loader --out-path output
  121. @endcode
  122. The `--no-loader` option is added because GLFW already provides a function for
  123. loading OpenGL and OpenGL ES function pointers, one that automatically uses the
  124. selected context creation API, and glad can call this instead of having to
  125. implement its own. There are several other command-line options as well. See
  126. the glad documentation for details.
  127. Add the generated `output/src/glad.c`, `output/include/glad/glad.h` and
  128. `output/include/KHR/khrplatform.h` files to your build. Then you need to
  129. include the glad header file, which will replace the OpenGL header of your
  130. development environment. By including the glad header before the GLFW header,
  131. it suppresses the development environment's OpenGL or OpenGL ES header.
  132. @code
  133. #include <glad/glad.h>
  134. #include <GLFW/glfw3.h>
  135. @endcode
  136. Finally you need to initialize glad once you have a suitable current context.
  137. @code
  138. window = glfwCreateWindow(640, 480, "My Window", NULL, NULL);
  139. if (!window)
  140. {
  141. ...
  142. }
  143. glfwMakeContextCurrent(window);
  144. gladLoadGLLoader((GLADloadproc) glfwGetProcAddress);
  145. @endcode
  146. Once glad has been loaded, you have access to all OpenGL core and extension
  147. functions supported by both the context you created and the glad loader you
  148. generated and you are ready to start rendering.
  149. You can specify a minimum required OpenGL or OpenGL ES version with
  150. [context hints](@ref window_hints_ctx). If your needs are more complex, you can
  151. check the actual OpenGL or OpenGL ES version with
  152. [context attributes](@ref window_attribs_ctx), or you can check whether
  153. a specific version is supported by the current context with the
  154. `GLAD_GL_VERSION_x_x` booleans.
  155. @code
  156. if (GLAD_GL_VERSION_3_2)
  157. {
  158. // Call OpenGL 3.2+ specific code
  159. }
  160. @endcode
  161. To check whether a specific extension is supported, use the `GLAD_GL_xxx`
  162. booleans.
  163. @code
  164. if (GLAD_GL_ARB_debug_output)
  165. {
  166. // Use GL_ARB_debug_output
  167. }
  168. @endcode
  169. @subsection context_glext_manual Loading extensions manually
  170. __Do not use this technique__ unless it is absolutely necessary. An
  171. [extension loader library](@ref context_glext_auto) will save you a ton of
  172. tedious, repetitive, error prone work.
  173. To use a certain extension, you must first check whether the context supports
  174. that extension and then, if it introduces new functions, retrieve the pointers
  175. to those functions. GLFW provides @ref glfwExtensionSupported and @ref
  176. glfwGetProcAddress for manual loading of extensions and new API functions.
  177. This section will demonstrate manual loading of OpenGL extensions. The loading
  178. of OpenGL ES extensions is identical except for the name of the extension header.
  179. @subsubsection context_glext_header The glext.h header
  180. The `glext.h` extension header is a continually updated file that defines the
  181. interfaces for all OpenGL extensions. The latest version of this can always be
  182. found at the [OpenGL Registry](http://www.opengl.org/registry/). There are also
  183. extension headers for the various versions of OpenGL ES at the
  184. [OpenGL ES Registry](https://www.khronos.org/registry/gles/). It it strongly
  185. recommended that you use your own copy of the extension header, as the one
  186. included in your development environment may be several years out of date and
  187. may not include the extensions you wish to use.
  188. The header defines function pointer types for all functions of all extensions it
  189. supports. These have names like `PFNGLGETDEBUGMESSAGELOGARBPROC` (for
  190. `glGetDebugMessageLogARB`), i.e. the name is made uppercase and `PFN` (pointer
  191. to function) and `PROC` (procedure) are added to the ends.
  192. To include the extension header, define [GLFW_INCLUDE_GLEXT](@ref build_macros)
  193. before including the GLFW header.
  194. @code
  195. #define GLFW_INCLUDE_GLEXT
  196. #include <GLFW/glfw3.h>
  197. @endcode
  198. @subsubsection context_glext_string Checking for extensions
  199. A given machine may not actually support the extension (it may have older
  200. drivers or a graphics card that lacks the necessary hardware features), so it
  201. is necessary to check at run-time whether the context supports the extension.
  202. This is done with @ref glfwExtensionSupported.
  203. @code
  204. if (glfwExtensionSupported("GL_ARB_debug_output"))
  205. {
  206. // The extension is supported by the current context
  207. }
  208. @endcode
  209. The argument is a null terminated ASCII string with the extension name. If the
  210. extension is supported, @ref glfwExtensionSupported returns `GLFW_TRUE`,
  211. otherwise it returns `GLFW_FALSE`.
  212. @subsubsection context_glext_proc Fetching function pointers
  213. Many extensions, though not all, require the use of new OpenGL functions.
  214. These functions often do not have entry points in the client API libraries of
  215. your operating system, making it necessary to fetch them at run time. You can
  216. retrieve pointers to these functions with @ref glfwGetProcAddress.
  217. @code
  218. PFNGLGETDEBUGMESSAGELOGARBPROC pfnGetDebugMessageLog = glfwGetProcAddress("glGetDebugMessageLogARB");
  219. @endcode
  220. In general, you should avoid giving the function pointer variables the (exact)
  221. same name as the function, as this may confuse your linker. Instead, you can
  222. use a different prefix, like above, or some other naming scheme.
  223. Now that all the pieces have been introduced, here is what they might look like
  224. when used together.
  225. @code
  226. #define GLFW_INCLUDE_GLEXT
  227. #include <GLFW/glfw3.h>
  228. #define glGetDebugMessageLogARB pfnGetDebugMessageLog
  229. PFNGLGETDEBUGMESSAGELOGARBPROC pfnGetDebugMessageLog;
  230. // Flag indicating whether the extension is supported
  231. int has_ARB_debug_output = 0;
  232. void load_extensions(void)
  233. {
  234. if (glfwExtensionSupported("GL_ARB_debug_output"))
  235. {
  236. pfnGetDebugMessageLog = (PFNGLGETDEBUGMESSAGELOGARBPROC)
  237. glfwGetProcAddress("glGetDebugMessageLogARB");
  238. has_ARB_debug_output = 1;
  239. }
  240. }
  241. void some_function(void)
  242. {
  243. if (has_ARB_debug_output)
  244. {
  245. // Now the extension function can be called as usual
  246. glGetDebugMessageLogARB(...);
  247. }
  248. }
  249. @endcode
  250. */