glfw.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. /*
  2. * m3dview/glfw.c
  3. *
  4. * Copyright (C) 2019 bzt (bztsrc@gitlab)
  5. *
  6. * Permission is hereby granted, free of charge, to any person
  7. * obtaining a copy of this software and associated documentation
  8. * files (the "Software"), to deal in the Software without
  9. * restriction, including without limitation the rights to use, copy,
  10. * modify, merge, publish, distribute, sublicense, and/or sell copies
  11. * of the Software, and to permit persons to whom the Software is
  12. * furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be
  15. * included in all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  18. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  19. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  20. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  21. * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  22. * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  24. * DEALINGS IN THE SOFTWARE.
  25. *
  26. * @brief GLFW interface for the simple portable Model 3D viewer
  27. * https://gitlab.com/bztsrc/model3d
  28. *
  29. */
  30. #include "viewer.h"
  31. #include <gl.h>
  32. #include <glfw3.h>
  33. GLFWwindow *window;
  34. double px = 0, py = 0;
  35. int running = 1;
  36. /* the glfw error callback */
  37. void glfw_error(int error, const char *msg)
  38. {
  39. fprintf(stderr, "m3dview: glfw error %d: %s\n", error, msg);
  40. }
  41. /* process a keyboard event callback */
  42. void glfw_key(__attribute__((unused)) GLFWwindow *window, int key, __attribute__((unused)) int scancode,
  43. int action, __attribute__((unused)) int mods)
  44. {
  45. if(action != GLFW_PRESS) return;
  46. switch(key) {
  47. case GLFW_KEY_Q:
  48. case GLFW_KEY_ESCAPE: running = 0; glfwSetWindowShouldClose(window, GLFW_TRUE); break;
  49. case GLFW_KEY_UP: mousez++; break;
  50. case GLFW_KEY_DOWN: mousez--; break;
  51. case GLFW_KEY_LEFT: mousex = -10; mousey = 0; mousemove = 1; break;
  52. case GLFW_KEY_RIGHT: mousex = 10; mousey = 0; mousemove = 1; break;
  53. case GLFW_KEY_PAGE_UP: actionid--; break;
  54. case GLFW_KEY_TAB:
  55. case GLFW_KEY_PAGE_DOWN: actionid++; break;
  56. case GLFW_KEY_EQUAL: zoomin(); break;
  57. case GLFW_KEY_MINUS: zoomout(); break;
  58. case GLFW_KEY_COMMA: prevframe(); break;
  59. case GLFW_KEY_PERIOD: nextframe(); break;
  60. case GLFW_KEY_SPACE: continous(); break;
  61. case GLFW_KEY_M: domesh ^= 1; break;
  62. case GLFW_KEY_S: doskel ^= 1; break;
  63. case GLFW_KEY_0:
  64. case GLFW_KEY_1:
  65. case GLFW_KEY_2:
  66. case GLFW_KEY_3:
  67. case GLFW_KEY_4:
  68. case GLFW_KEY_5:
  69. case GLFW_KEY_6:
  70. case GLFW_KEY_7:
  71. case GLFW_KEY_8:
  72. case GLFW_KEY_9: fpsdiv(key-GLFW_KEY_0); break;
  73. }
  74. }
  75. /* mouse event callback */
  76. void glfw_mouse(__attribute__((unused)) GLFWwindow *window, int button, int action, __attribute__((unused)) int mods) {
  77. int s = action == GLFW_PRESS;
  78. if (button == GLFW_MOUSE_BUTTON_LEFT) mousebtn = s;
  79. if (s && button == GLFW_MOUSE_BUTTON_MIDDLE) zoomin();
  80. if (s && button == GLFW_MOUSE_BUTTON_RIGHT) zoomout();
  81. }
  82. /* scrolling event callback */
  83. void glfw_scroll(__attribute__((unused)) GLFWwindow *window, __attribute__((unused)) double xdelta, double ydelta) {
  84. if(ydelta < 0.0) zoomout();
  85. else zoomin();
  86. }
  87. /**
  88. * Set window title
  89. */
  90. void set_title(char *title)
  91. {
  92. glfwSetWindowTitle(window, title);
  93. }
  94. /**
  95. * Main procedure. Set up and main loop
  96. */
  97. int main(int argc, char **argv)
  98. {
  99. double mx, my;
  100. load(argc, argv);
  101. if (!glfwInit() || !(window = glfwCreateWindow(screenw, screenh, wintitle, NULL, NULL)))
  102. error("unable to initialize glfw");
  103. glfwSetErrorCallback(glfw_error);
  104. glfwMakeContextCurrent(window);
  105. glfwSwapInterval(1);
  106. glfwSetKeyCallback(window, glfw_key);
  107. glfwSetMouseButtonCallback(window, glfw_mouse);
  108. glfwSetScrollCallback(window, glfw_scroll);
  109. setupgl();
  110. while(running) {
  111. /* handle window resize */
  112. glfwGetFramebufferSize(window, &screenw, &screenh);
  113. glViewport(0, 0, screenw, screenh);
  114. /* handle mouse movement */
  115. glfwGetCursorPos(window, &mx, &my);
  116. if(mx != px || my != py) {
  117. mousex = (int)(mx - px);
  118. mousey = (int)(my - py);
  119. px = mx; py = my;
  120. mousemove = mousebtn;
  121. }
  122. /* render scene */
  123. display((int)(glfwGetTime()*1000));
  124. glfwSwapBuffers(window);
  125. glfwPollEvents();
  126. if (glfwWindowShouldClose(window)) break;
  127. }
  128. glfwDestroyWindow(window);
  129. glfwTerminate();
  130. cleanup();
  131. return 0;
  132. }