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.

317 line
8.7 KiB

5 年之前
  1. //========================================================================
  2. // Cursor & input mode tests
  3. // Copyright (c) Camilla Berglund <elmindreda@glfw.org>
  4. //
  5. // This software is provided 'as-is', without any express or implied
  6. // warranty. In no event will the authors be held liable for any damages
  7. // arising from the use of this software.
  8. //
  9. // Permission is granted to anyone to use this software for any purpose,
  10. // including commercial applications, and to alter it and redistribute it
  11. // freely, subject to the following restrictions:
  12. //
  13. // 1. The origin of this software must not be misrepresented; you must not
  14. // claim that you wrote the original software. If you use this software
  15. // in a product, an acknowledgment in the product documentation would
  16. // be appreciated but is not required.
  17. //
  18. // 2. Altered source versions must be plainly marked as such, and must not
  19. // be misrepresented as being the original software.
  20. //
  21. // 3. This notice may not be removed or altered from any source
  22. // distribution.
  23. //
  24. //========================================================================
  25. //
  26. // This test provides an interface to the cursor image and cursor mode
  27. // parts of the API.
  28. //
  29. // Custom cursor image generation by urraka.
  30. //
  31. //========================================================================
  32. #include <glad/glad.h>
  33. #include <GLFW/glfw3.h>
  34. #if defined(_MSC_VER)
  35. // Make MS math.h define M_PI
  36. #define _USE_MATH_DEFINES
  37. #endif
  38. #include <math.h>
  39. #include <stdio.h>
  40. #include <stdlib.h>
  41. #define CURSOR_FRAME_COUNT 60
  42. static double cursor_x;
  43. static double cursor_y;
  44. static int swap_interval = 1;
  45. static int wait_events = GLFW_TRUE;
  46. static int animate_cursor = GLFW_FALSE;
  47. static int track_cursor = GLFW_FALSE;
  48. static GLFWcursor* standard_cursors[6];
  49. static void error_callback(int error, const char* description)
  50. {
  51. fprintf(stderr, "Error: %s\n", description);
  52. }
  53. static float star(int x, int y, float t)
  54. {
  55. const float c = 64 / 2.f;
  56. const float i = (0.25f * (float) sin(2.f * M_PI * t) + 0.75f);
  57. const float k = 64 * 0.046875f * i;
  58. const float dist = (float) sqrt((x - c) * (x - c) + (y - c) * (y - c));
  59. const float salpha = 1.f - dist / c;
  60. const float xalpha = (float) x == c ? c : k / (float) fabs(x - c);
  61. const float yalpha = (float) y == c ? c : k / (float) fabs(y - c);
  62. return (float) fmax(0.f, fmin(1.f, i * salpha * 0.2f + salpha * xalpha * yalpha));
  63. }
  64. static GLFWcursor* create_cursor_frame(float t)
  65. {
  66. int i = 0, x, y;
  67. unsigned char buffer[64 * 64 * 4];
  68. const GLFWimage image = { 64, 64, buffer };
  69. for (y = 0; y < image.width; y++)
  70. {
  71. for (x = 0; x < image.height; x++)
  72. {
  73. buffer[i++] = 255;
  74. buffer[i++] = 255;
  75. buffer[i++] = 255;
  76. buffer[i++] = (unsigned char) (255 * star(x, y, t));
  77. }
  78. }
  79. return glfwCreateCursor(&image, image.width / 2, image.height / 2);
  80. }
  81. static void cursor_position_callback(GLFWwindow* window, double x, double y)
  82. {
  83. printf("%0.3f: Cursor position: %f %f (%+f %+f)\n",
  84. glfwGetTime(),
  85. x, y, x - cursor_x, y - cursor_y);
  86. cursor_x = x;
  87. cursor_y = y;
  88. }
  89. static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
  90. {
  91. if (action != GLFW_PRESS)
  92. return;
  93. switch (key)
  94. {
  95. case GLFW_KEY_A:
  96. {
  97. animate_cursor = !animate_cursor;
  98. if (!animate_cursor)
  99. glfwSetCursor(window, NULL);
  100. break;
  101. }
  102. case GLFW_KEY_ESCAPE:
  103. {
  104. if (glfwGetInputMode(window, GLFW_CURSOR) != GLFW_CURSOR_DISABLED)
  105. {
  106. glfwSetWindowShouldClose(window, GLFW_TRUE);
  107. break;
  108. }
  109. /* FALLTHROUGH */
  110. }
  111. case GLFW_KEY_N:
  112. glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
  113. printf("(( cursor is normal ))\n");
  114. break;
  115. case GLFW_KEY_D:
  116. glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
  117. printf("(( cursor is disabled ))\n");
  118. break;
  119. case GLFW_KEY_H:
  120. glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
  121. printf("(( cursor is hidden ))\n");
  122. break;
  123. case GLFW_KEY_SPACE:
  124. swap_interval = 1 - swap_interval;
  125. printf("(( swap interval: %i ))\n", swap_interval);
  126. glfwSwapInterval(swap_interval);
  127. break;
  128. case GLFW_KEY_W:
  129. wait_events = !wait_events;
  130. printf("(( %sing for events ))\n", wait_events ? "wait" : "poll");
  131. break;
  132. case GLFW_KEY_T:
  133. track_cursor = !track_cursor;
  134. break;
  135. case GLFW_KEY_0:
  136. glfwSetCursor(window, NULL);
  137. break;
  138. case GLFW_KEY_1:
  139. glfwSetCursor(window, standard_cursors[0]);
  140. break;
  141. case GLFW_KEY_2:
  142. glfwSetCursor(window, standard_cursors[1]);
  143. break;
  144. case GLFW_KEY_3:
  145. glfwSetCursor(window, standard_cursors[2]);
  146. break;
  147. case GLFW_KEY_4:
  148. glfwSetCursor(window, standard_cursors[3]);
  149. break;
  150. case GLFW_KEY_5:
  151. glfwSetCursor(window, standard_cursors[4]);
  152. break;
  153. case GLFW_KEY_6:
  154. glfwSetCursor(window, standard_cursors[5]);
  155. break;
  156. }
  157. }
  158. int main(void)
  159. {
  160. int i;
  161. GLFWwindow* window;
  162. GLFWcursor* star_cursors[CURSOR_FRAME_COUNT];
  163. GLFWcursor* current_frame = NULL;
  164. glfwSetErrorCallback(error_callback);
  165. if (!glfwInit())
  166. exit(EXIT_FAILURE);
  167. for (i = 0; i < CURSOR_FRAME_COUNT; i++)
  168. {
  169. star_cursors[i] = create_cursor_frame(i / (float) CURSOR_FRAME_COUNT);
  170. if (!star_cursors[i])
  171. {
  172. glfwTerminate();
  173. exit(EXIT_FAILURE);
  174. }
  175. }
  176. for (i = 0; i < sizeof(standard_cursors) / sizeof(standard_cursors[0]); i++)
  177. {
  178. const int shapes[] = {
  179. GLFW_ARROW_CURSOR,
  180. GLFW_IBEAM_CURSOR,
  181. GLFW_CROSSHAIR_CURSOR,
  182. GLFW_HAND_CURSOR,
  183. GLFW_HRESIZE_CURSOR,
  184. GLFW_VRESIZE_CURSOR
  185. };
  186. standard_cursors[i] = glfwCreateStandardCursor(shapes[i]);
  187. if (!standard_cursors[i])
  188. {
  189. glfwTerminate();
  190. exit(EXIT_FAILURE);
  191. }
  192. }
  193. window = glfwCreateWindow(640, 480, "Cursor Test", NULL, NULL);
  194. if (!window)
  195. {
  196. glfwTerminate();
  197. exit(EXIT_FAILURE);
  198. }
  199. glfwMakeContextCurrent(window);
  200. gladLoadGLLoader((GLADloadproc) glfwGetProcAddress);
  201. glfwGetCursorPos(window, &cursor_x, &cursor_y);
  202. printf("Cursor position: %f %f\n", cursor_x, cursor_y);
  203. glfwSetCursorPosCallback(window, cursor_position_callback);
  204. glfwSetKeyCallback(window, key_callback);
  205. while (!glfwWindowShouldClose(window))
  206. {
  207. glClear(GL_COLOR_BUFFER_BIT);
  208. if (track_cursor)
  209. {
  210. int wnd_width, wnd_height, fb_width, fb_height;
  211. float scale;
  212. glfwGetWindowSize(window, &wnd_width, &wnd_height);
  213. glfwGetFramebufferSize(window, &fb_width, &fb_height);
  214. scale = (float) fb_width / (float) wnd_width;
  215. glViewport(0, 0, fb_width, fb_height);
  216. glMatrixMode(GL_PROJECTION);
  217. glLoadIdentity();
  218. glOrtho(0.f, fb_width, 0.f, fb_height, 0.f, 1.f);
  219. glBegin(GL_LINES);
  220. glVertex2f(0.f, (GLfloat) (fb_height - cursor_y * scale));
  221. glVertex2f((GLfloat) fb_width, (GLfloat) (fb_height - cursor_y * scale));
  222. glVertex2f((GLfloat) cursor_x * scale, 0.f);
  223. glVertex2f((GLfloat) cursor_x * scale, (GLfloat) fb_height);
  224. glEnd();
  225. }
  226. glfwSwapBuffers(window);
  227. if (animate_cursor)
  228. {
  229. const int i = (int) (glfwGetTime() * 30.0) % CURSOR_FRAME_COUNT;
  230. if (current_frame != star_cursors[i])
  231. {
  232. glfwSetCursor(window, star_cursors[i]);
  233. current_frame = star_cursors[i];
  234. }
  235. }
  236. else
  237. current_frame = NULL;
  238. if (wait_events)
  239. {
  240. if (animate_cursor)
  241. glfwWaitEventsTimeout(1.0 / 30.0);
  242. else
  243. glfwWaitEvents();
  244. }
  245. else
  246. glfwPollEvents();
  247. // Workaround for an issue with msvcrt and mintty
  248. fflush(stdout);
  249. }
  250. glfwDestroyWindow(window);
  251. for (i = 0; i < CURSOR_FRAME_COUNT; i++)
  252. glfwDestroyCursor(star_cursors[i]);
  253. for (i = 0; i < sizeof(standard_cursors) / sizeof(standard_cursors[0]); i++)
  254. glfwDestroyCursor(standard_cursors[i]);
  255. glfwTerminate();
  256. exit(EXIT_SUCCESS);
  257. }