Platformer in OpenGL
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

665 Zeilen
20 KiB

vor 5 Jahren
  1. /*!
  2. @page input_guide Input guide
  3. @tableofcontents
  4. This guide introduces the input related functions of GLFW. For details on
  5. a specific function in this category, see the @ref input. There are also guides
  6. for the other areas of GLFW.
  7. - @ref intro_guide
  8. - @ref window_guide
  9. - @ref context_guide
  10. - @ref vulkan_guide
  11. - @ref monitor_guide
  12. GLFW provides many kinds of input. While some can only be polled, like time, or
  13. only received via callbacks, like scrolling, there are those that provide both
  14. callbacks and polling. Where a callback is provided, that is the recommended
  15. way to receive that kind of input. The more you can use callbacks the less time
  16. your users' machines will need to spend polling.
  17. All input callbacks receive a window handle. By using the
  18. [window user pointer](@ref window_userptr), you can access non-global structures
  19. or objects from your callbacks.
  20. To get a better feel for how the various events callbacks behave, run the
  21. `events` test program. It register every callback supported by GLFW and prints
  22. out all arguments provided for every event, along with time and sequence
  23. information.
  24. @section events Event processing
  25. GLFW needs to communicate regularly with the window system both in order to
  26. receive events and to show that the application hasn't locked up. Event
  27. processing must be done regularly while you have any windows and is normally
  28. done each frame after [buffer swapping](@ref buffer_swap). Even when you have
  29. no windows, event polling needs to be done in order to receive monitor
  30. connection events.
  31. There are two functions for processing pending events. @ref glfwPollEvents,
  32. processes only those events that have already been received and then returns
  33. immediately.
  34. @code
  35. glfwPollEvents();
  36. @endcode
  37. This is the best choice when rendering continually, like most games do.
  38. If you only need to update the contents of the window when you receive new
  39. input, @ref glfwWaitEvents is a better choice.
  40. @code
  41. glfwWaitEvents();
  42. @endcode
  43. It puts the thread to sleep until at least one event has been received and then
  44. processes all received events. This saves a great deal of CPU cycles and is
  45. useful for, for example, editing tools. There must be at least one GLFW window
  46. for this function to sleep.
  47. If you want to wait for events but have UI elements that need periodic updates,
  48. call @ref glfwWaitEventsTimeout.
  49. @code
  50. glfwWaitEventsTimeout(0.7);
  51. @endcode
  52. It puts the thread to sleep until at least one event has been received, or until
  53. the specified number of seconds have elapsed. It then processes any received
  54. events.
  55. If the main thread is sleeping in @ref glfwWaitEvents, you can wake it from
  56. another thread by posting an empty event to the event queue with @ref
  57. glfwPostEmptyEvent.
  58. @code
  59. glfwPostEmptyEvent();
  60. @endcode
  61. Do not assume that callbacks will _only_ be called through either of the above
  62. functions. While it is necessary to process events in the event queue, some
  63. window systems will send some events directly to the application, which in turn
  64. causes callbacks to be called outside of regular event processing.
  65. @section input_keyboard Keyboard input
  66. GLFW divides keyboard input into two categories; key events and character
  67. events. Key events relate to actual physical keyboard keys, whereas character
  68. events relate to the Unicode code points generated by pressing some of them.
  69. Keys and characters do not map 1:1. A single key press may produce several
  70. characters, and a single character may require several keys to produce. This
  71. may not be the case on your machine, but your users are likely not all using the
  72. same keyboard layout, input method or even operating system as you.
  73. @subsection input_key Key input
  74. If you wish to be notified when a physical key is pressed or released or when it
  75. repeats, set a key callback.
  76. @code
  77. glfwSetKeyCallback(window, key_callback);
  78. @endcode
  79. The callback function receives the [keyboard key](@ref keys), platform-specific
  80. scancode, key action and [modifier bits](@ref mods).
  81. @code
  82. void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
  83. {
  84. if (key == GLFW_KEY_E && action == GLFW_PRESS)
  85. activate_airship();
  86. }
  87. @endcode
  88. The action is one of `GLFW_PRESS`, `GLFW_REPEAT` or `GLFW_RELEASE`. The key
  89. will be `GLFW_KEY_UNKNOWN` if GLFW lacks a key token for it, for example
  90. _E-mail_ and _Play_ keys.
  91. The scancode is unique for every key, regardless of whether it has a key token.
  92. Scancodes are platform-specific but consistent over time, so keys will have
  93. different scancodes depending on the platform but they are safe to save to disk.
  94. Key states for [named keys](@ref keys) are also saved in per-window state arrays
  95. that can be polled with @ref glfwGetKey.
  96. @code
  97. int state = glfwGetKey(window, GLFW_KEY_E);
  98. if (state == GLFW_PRESS)
  99. activate_airship();
  100. @endcode
  101. The returned state is one of `GLFW_PRESS` or `GLFW_RELEASE`.
  102. This function only returns cached key event state. It does not poll the
  103. system for the current state of the key.
  104. Whenever you poll state, you risk missing the state change you are looking for.
  105. If a pressed key is released again before you poll its state, you will have
  106. missed the key press. The recommended solution for this is to use a
  107. key callback, but there is also the `GLFW_STICKY_KEYS` input mode.
  108. @code
  109. glfwSetInputMode(window, GLFW_STICKY_KEYS, 1);
  110. @endcode
  111. When sticky keys mode is enabled, the pollable state of a key will remain
  112. `GLFW_PRESS` until the state of that key is polled with @ref glfwGetKey. Once
  113. it has been polled, if a key release event had been processed in the meantime,
  114. the state will reset to `GLFW_RELEASE`, otherwise it will remain `GLFW_PRESS`.
  115. The `GLFW_KEY_LAST` constant holds the highest value of any
  116. [named key](@ref keys).
  117. @subsection input_char Text input
  118. GLFW supports text input in the form of a stream of
  119. [Unicode code points](https://en.wikipedia.org/wiki/Unicode), as produced by the
  120. operating system text input system. Unlike key input, text input obeys keyboard
  121. layouts and modifier keys and supports composing characters using
  122. [dead keys](https://en.wikipedia.org/wiki/Dead_key). Once received, you can
  123. encode the code points into
  124. [UTF-8](https://en.wikipedia.org/wiki/UTF-8) or any other encoding you prefer.
  125. Because an `unsigned int` is 32 bits long on all platforms supported by GLFW,
  126. you can treat the code point argument as native endian
  127. [UTF-32](https://en.wikipedia.org/wiki/UTF-32).
  128. There are two callbacks for receiving Unicode code points. If you wish to
  129. offer regular text input, set a character callback.
  130. @code
  131. glfwSetCharCallback(window, character_callback);
  132. @endcode
  133. The callback function receives Unicode code points for key events that would
  134. have led to regular text input and generally behaves as a standard text field on
  135. that platform.
  136. @code
  137. void character_callback(GLFWwindow* window, unsigned int codepoint)
  138. {
  139. }
  140. @endcode
  141. If you wish to receive even those Unicode code points generated with modifier
  142. key combinations that a plain text field would ignore, or just want to know
  143. exactly what modifier keys were used, set a character with modifiers callback.
  144. @code
  145. glfwSetCharModsCallback(window, charmods_callback);
  146. @endcode
  147. The callback function receives Unicode code points and
  148. [modifier bits](@ref mods).
  149. @code
  150. void charmods_callback(GLFWwindow* window, unsigned int codepoint, int mods)
  151. {
  152. }
  153. @endcode
  154. @subsection input_key_name Key names
  155. If you wish to refer to keys by name, you can query the keyboard layout
  156. dependent name of printable keys with @ref glfwGetKeyName.
  157. @code
  158. const char* key_name = glfwGetKeyName(GLFW_KEY_W, 0);
  159. show_tutorial_hint("Press %s to move forward", key_name);
  160. @endcode
  161. This function can handle both [keys and scancodes](@ref input_key). If the
  162. specified key is `GLFW_KEY_UNKNOWN` then the scancode is used, otherwise it is
  163. ignored. This matches the behavior of the key callback, meaning the callback
  164. arguments can always be passed unmodified to this function.
  165. @section input_mouse Mouse input
  166. Mouse input comes in many forms, including cursor motion, button presses and
  167. scrolling offsets. The cursor appearance can also be changed, either to
  168. a custom image or a standard cursor shape from the system theme.
  169. @subsection cursor_pos Cursor position
  170. If you wish to be notified when the cursor moves over the window, set a cursor
  171. position callback.
  172. @code
  173. glfwSetCursorPosCallback(window, cursor_pos_callback);
  174. @endcode
  175. The callback functions receives the cursor position, measured in screen
  176. coordinates but relative to the top-left corner of the window client area. On
  177. platforms that provide it, the full sub-pixel cursor position is passed on.
  178. @code
  179. static void cursor_position_callback(GLFWwindow* window, double xpos, double ypos)
  180. {
  181. }
  182. @endcode
  183. The cursor position is also saved per-window and can be polled with @ref
  184. glfwGetCursorPos.
  185. @code
  186. double xpos, ypos;
  187. glfwGetCursorPos(window, &xpos, &ypos);
  188. @endcode
  189. @subsection cursor_mode Cursor modes
  190. The `GLFW_CURSOR` input mode provides several cursor modes for special forms of
  191. mouse motion input. By default, the cursor mode is `GLFW_CURSOR_NORMAL`,
  192. meaning the regular arrow cursor (or another cursor set with @ref glfwSetCursor)
  193. is used and cursor motion is not limited.
  194. If you wish to implement mouse motion based camera controls or other input
  195. schemes that require unlimited mouse movement, set the cursor mode to
  196. `GLFW_CURSOR_DISABLED`.
  197. @code
  198. glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
  199. @endcode
  200. This will hide the cursor and lock it to the specified window. GLFW will then
  201. take care of all the details of cursor re-centering and offset calculation and
  202. providing the application with a virtual cursor position. This virtual position
  203. is provided normally via both the cursor position callback and through polling.
  204. @note You should not implement your own version of this functionality using
  205. other features of GLFW. It is not supported and will not work as robustly as
  206. `GLFW_CURSOR_DISABLED`.
  207. If you just wish the cursor to become hidden when it is over a window, set
  208. the cursor mode to `GLFW_CURSOR_HIDDEN`.
  209. @code
  210. glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
  211. @endcode
  212. This mode puts no limit on the motion of the cursor.
  213. To exit out of either of these special modes, restore the `GLFW_CURSOR_NORMAL`
  214. cursor mode.
  215. @code
  216. glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
  217. @endcode
  218. @subsection cursor_object Cursor objects
  219. GLFW supports creating both custom and system theme cursor images, encapsulated
  220. as @ref GLFWcursor objects. They are created with @ref glfwCreateCursor or @ref
  221. glfwCreateStandardCursor and destroyed with @ref glfwDestroyCursor, or @ref
  222. glfwTerminate, if any remain.
  223. @subsubsection cursor_custom Custom cursor creation
  224. A custom cursor is created with @ref glfwCreateCursor, which returns a handle to
  225. the created cursor object. For example, this creates a 16x16 white square
  226. cursor with the hot-spot in the upper-left corner:
  227. @code
  228. unsigned char pixels[16 * 16 * 4];
  229. memset(pixels, 0xff, sizeof(pixels));
  230. GLFWimage image;
  231. image.width = 16;
  232. image.height = 16;
  233. image.pixels = pixels;
  234. GLFWcursor* cursor = glfwCreateCursor(&image, 0, 0);
  235. @endcode
  236. If cursor creation fails, `NULL` will be returned, so it is necessary to check
  237. the return value.
  238. The image data is 32-bit, little-endian, non-premultiplied RGBA, i.e. eight bits
  239. per channel. The pixels are arranged canonically as sequential rows, starting
  240. from the top-left corner.
  241. @subsubsection cursor_standard Standard cursor creation
  242. A cursor with a [standard shape](@ref shapes) from the current system cursor
  243. theme can be can be created with @ref glfwCreateStandardCursor.
  244. @code
  245. GLFWcursor* cursor = glfwCreateStandardCursor(GLFW_HRESIZE_CURSOR);
  246. @endcode
  247. These cursor objects behave in the exact same way as those created with @ref
  248. glfwCreateCursor except that the system cursor theme provides the actual image.
  249. @subsubsection cursor_destruction Cursor destruction
  250. When a cursor is no longer needed, destroy it with @ref glfwDestroyCursor.
  251. @code
  252. glfwDestroyCursor(cursor);
  253. @endcode
  254. Cursor destruction always succeeds. All cursors remaining when @ref
  255. glfwTerminate is called are destroyed as well.
  256. @subsubsection cursor_set Cursor setting
  257. A cursor can be set as current for a window with @ref glfwSetCursor.
  258. @code
  259. glfwSetCursor(window, cursor);
  260. @endcode
  261. Once set, the cursor image will be used as long as the system cursor is over the
  262. client area of the window and the [cursor mode](@ref cursor_mode) is set
  263. to `GLFW_CURSOR_NORMAL`.
  264. A single cursor may be set for any number of windows.
  265. To remove a cursor from a window, set the cursor of that window to `NULL`.
  266. @code
  267. glfwSetCursor(window, NULL);
  268. @endcode
  269. When a cursor is destroyed, it is removed from any window where it is set. This
  270. does not affect the cursor modes of those windows.
  271. @subsection cursor_enter Cursor enter/leave events
  272. If you wish to be notified when the cursor enters or leaves the client area of
  273. a window, set a cursor enter/leave callback.
  274. @code
  275. glfwSetCursorEnterCallback(window, cursor_enter_callback);
  276. @endcode
  277. The callback function receives the new classification of the cursor.
  278. @code
  279. void cursor_enter_callback(GLFWwindow* window, int entered)
  280. {
  281. if (entered)
  282. {
  283. // The cursor entered the client area of the window
  284. }
  285. else
  286. {
  287. // The cursor left the client area of the window
  288. }
  289. }
  290. @endcode
  291. @subsection input_mouse_button Mouse button input
  292. If you wish to be notified when a mouse button is pressed or released, set
  293. a mouse button callback.
  294. @code
  295. glfwSetMouseButtonCallback(window, mouse_button_callback);
  296. @endcode
  297. The callback function receives the [mouse button](@ref buttons), button action
  298. and [modifier bits](@ref mods).
  299. @code
  300. void mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
  301. {
  302. if (button == GLFW_MOUSE_BUTTON_RIGHT && action == GLFW_PRESS)
  303. popup_menu();
  304. }
  305. @endcode
  306. The action is one of `GLFW_PRESS` or `GLFW_RELEASE`.
  307. Mouse button states for [named buttons](@ref buttons) are also saved in
  308. per-window state arrays that can be polled with @ref glfwGetMouseButton.
  309. @code
  310. int state = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT);
  311. if (state == GLFW_PRESS)
  312. upgrade_cow();
  313. @endcode
  314. The returned state is one of `GLFW_PRESS` or `GLFW_RELEASE`.
  315. This function only returns cached mouse button event state. It does not poll
  316. the system for the current state of the mouse button.
  317. Whenever you poll state, you risk missing the state change you are looking for.
  318. If a pressed mouse button is released again before you poll its state, you will have
  319. missed the button press. The recommended solution for this is to use a
  320. mouse button callback, but there is also the `GLFW_STICKY_MOUSE_BUTTONS`
  321. input mode.
  322. @code
  323. glfwSetInputMode(window, GLFW_STICKY_MOUSE_BUTTONS, 1);
  324. @endcode
  325. When sticky mouse buttons mode is enabled, the pollable state of a mouse button
  326. will remain `GLFW_PRESS` until the state of that button is polled with @ref
  327. glfwGetMouseButton. Once it has been polled, if a mouse button release event
  328. had been processed in the meantime, the state will reset to `GLFW_RELEASE`,
  329. otherwise it will remain `GLFW_PRESS`.
  330. The `GLFW_MOUSE_BUTTON_LAST` constant holds the highest value of any
  331. [named button](@ref buttons).
  332. @subsection scrolling Scroll input
  333. If you wish to be notified when the user scrolls, whether with a mouse wheel or
  334. touchpad gesture, set a scroll callback.
  335. @code
  336. glfwSetScrollCallback(window, scroll_callback);
  337. @endcode
  338. The callback function receives two-dimensional scroll offsets.
  339. @code
  340. void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
  341. {
  342. }
  343. @endcode
  344. A simple mouse wheel, being vertical, provides offsets along the Y-axis.
  345. @section joystick Joystick input
  346. The joystick functions expose connected joysticks and controllers, with both
  347. referred to as joysticks. It supports up to sixteen joysticks, ranging from
  348. `GLFW_JOYSTICK_1`, `GLFW_JOYSTICK_2` up to `GLFW_JOYSTICK_LAST`. You can test
  349. whether a [joystick](@ref joysticks) is present with @ref glfwJoystickPresent.
  350. @code
  351. int present = glfwJoystickPresent(GLFW_JOYSTICK_1);
  352. @endcode
  353. When GLFW is initialized, detected joysticks are added to to the beginning of
  354. the array, starting with `GLFW_JOYSTICK_1`. Once a joystick is detected, it
  355. keeps its assigned index until it is disconnected, so as joysticks are connected
  356. and disconnected, they will become spread out.
  357. Joystick state is updated as needed when a joystick function is called and does
  358. not require a window to be created or @ref glfwPollEvents or @ref glfwWaitEvents
  359. to be called.
  360. @subsection joystick_axis Joystick axis states
  361. The positions of all axes of a joystick are returned by @ref
  362. glfwGetJoystickAxes. See the reference documentation for the lifetime of the
  363. returned array.
  364. @code
  365. int count;
  366. const float* axes = glfwGetJoystickAxes(GLFW_JOYSTICK_1, &count);
  367. @endcode
  368. Each element in the returned array is a value between -1.0 and 1.0.
  369. @subsection joystick_button Joystick button states
  370. The states of all buttons of a joystick are returned by @ref
  371. glfwGetJoystickButtons. See the reference documentation for the lifetime of the
  372. returned array.
  373. @code
  374. int count;
  375. const unsigned char* axes = glfwGetJoystickButtons(GLFW_JOYSTICK_1, &count);
  376. @endcode
  377. Each element in the returned array is either `GLFW_PRESS` or `GLFW_RELEASE`.
  378. @subsection joystick_name Joystick name
  379. The human-readable, UTF-8 encoded name of a joystick is returned by @ref
  380. glfwGetJoystickName. See the reference documentation for the lifetime of the
  381. returned string.
  382. @code
  383. const char* name = glfwGetJoystickName(GLFW_JOYSTICK_1);
  384. @endcode
  385. Joystick names are not guaranteed to be unique. Two joysticks of the same model
  386. and make may have the same name. Only the [joystick token](@ref joysticks) is
  387. guaranteed to be unique, and only until that joystick is disconnected.
  388. @subsection joystick_event Joystick configuration changes
  389. If you wish to be notified when a joystick is connected or disconnected, set
  390. a joystick callback.
  391. @code
  392. glfwSetJoystickCallback(joystick_callback);
  393. @endcode
  394. The callback function receives the ID of the joystick that has been connected
  395. and disconnected and the event that occurred.
  396. @code
  397. void joystick_callback(int joy, int event)
  398. {
  399. if (event == GLFW_CONNECTED)
  400. {
  401. // The joystick was connected
  402. }
  403. else if (event == GLFW_DISCONNECTED)
  404. {
  405. // The joystick was disconnected
  406. }
  407. }
  408. @endcode
  409. @section time Time input
  410. GLFW provides high-resolution time input, in seconds, with @ref glfwGetTime.
  411. @code
  412. double seconds = glfwGetTime();
  413. @endcode
  414. It returns the number of seconds since the timer was started when the library
  415. was initialized with @ref glfwInit. The platform-specific time sources used
  416. usually have micro- or nanosecond resolution.
  417. You can modify the reference time with @ref glfwSetTime.
  418. @code
  419. glfwSetTime(4.0);
  420. @endcode
  421. This sets the timer to the specified time, in seconds.
  422. You can also access the raw timer value, measured in 1 / frequency
  423. seconds, with @ref glfwGetTimerValue.
  424. @code
  425. uint64_t value = glfwGetTimerValue();
  426. @endcode
  427. The frequency of the raw timer varies depending on what time sources are
  428. available on the machine. You can query its frequency, in Hz, with @ref
  429. glfwGetTimerFrequency.
  430. @code
  431. uint64_t freqency = glfwGetTimerFrequency();
  432. @endcode
  433. @section clipboard Clipboard input and output
  434. If the system clipboard contains a UTF-8 encoded string or if it can be
  435. converted to one, you can retrieve it with @ref glfwGetClipboardString. See the
  436. reference documentation for the lifetime of the returned string.
  437. @code
  438. const char* text = glfwGetClipboardString(window);
  439. if (text)
  440. insert_text(text);
  441. @endcode
  442. If the clipboard is empty or if its contents could not be converted, `NULL` is
  443. returned.
  444. The contents of the system clipboard can be set to a UTF-8 encoded string with
  445. @ref glfwSetClipboardString.
  446. @code
  447. glfwSetClipboardString(window, "A string with words in it");
  448. @endcode
  449. The clipboard functions take a window handle argument because some window
  450. systems require a window to communicate with the system clipboard. Any valid
  451. window may be used.
  452. @section path_drop Path drop input
  453. If you wish to receive the paths of files and/or directories dropped on
  454. a window, set a file drop callback.
  455. @code
  456. glfwSetDropCallback(window, drop_callback);
  457. @endcode
  458. The callback function receives an array of paths encoded as UTF-8.
  459. @code
  460. void drop_callback(GLFWwindow* window, int count, const char** paths)
  461. {
  462. int i;
  463. for (i = 0; i < count; i++)
  464. handle_dropped_file(paths[i]);
  465. }
  466. @endcode
  467. The path array and its strings are only valid until the file drop callback
  468. returns, as they may have been generated specifically for that event. You need
  469. to make a deep copy of the array if you want to keep the paths.
  470. */