Window.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. #include "rendering/Window.h"
  2. static int glfwCounter = 0;
  3. static int glewCounter = 0;
  4. Window::Window() : window(nullptr), size({0, 0}), textInput(nullptr) {
  5. if(glfwCounter == 0 && !glfwInit()) {
  6. return;
  7. }
  8. glfwCounter++;
  9. }
  10. Window::~Window() {
  11. if(window != nullptr) {
  12. glfwDestroyWindow(window);
  13. }
  14. if(glfwCounter > 0 && --glfwCounter == 0) {
  15. glfwTerminate();
  16. }
  17. }
  18. Error Window::open(const WindowOptions& options) {
  19. if(glfwCounter <= 0) {
  20. return {"could not initialize GLFW"};
  21. }
  22. glfwDefaultWindowHints();
  23. glfwWindowHint(GLFW_VISIBLE, false);
  24. glfwWindowHint(GLFW_RESIZABLE, true);
  25. glfwWindowHint(GLFW_DECORATED, !options.fullscreen);
  26. glfwWindowHint(GLFW_DOUBLEBUFFER, true);
  27. if(options.es) {
  28. glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
  29. } else {
  30. glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
  31. }
  32. glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, options.majorVersion);
  33. glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, options.minorVersion);
  34. GLFWmonitor* monitor =
  35. options.fullscreen ? glfwGetPrimaryMonitor() : nullptr;
  36. window = glfwCreateWindow(options.size.width, options.size.height,
  37. options.name, monitor, nullptr);
  38. if(window == nullptr) {
  39. return {"could not create window"};
  40. }
  41. size = options.size;
  42. glfwSetWindowUserPointer(window, this);
  43. glfwSetKeyCallback(window, onKey);
  44. glfwSetCharCallback(window, onChar);
  45. glfwSetFramebufferSizeCallback(window, onResize);
  46. glfwSetMouseButtonCallback(window, onMouse);
  47. glfwSetCursorPosCallback(window, onMouseMove);
  48. glfwMakeContextCurrent(window);
  49. glfwSwapInterval(options.vsync);
  50. if(glewCounter == 0) {
  51. GLenum err = glewInit();
  52. if(err != GLEW_OK) {
  53. Error error;
  54. error.message.clear()
  55. .append("could not initialize GLEW: ")
  56. .append(glewGetErrorString(err));
  57. return error;
  58. }
  59. }
  60. glewCounter++;
  61. return {};
  62. }
  63. const Clock& Window::getFrameClock() const {
  64. return fps;
  65. }
  66. const Clock& Window::getTickClock() const {
  67. return tps;
  68. }
  69. const Size& Window::getSize() const {
  70. return size;
  71. }
  72. void Window::trapCursor(bool trap) {
  73. glfwSetInputMode(window, GLFW_CURSOR,
  74. trap ? GLFW_CURSOR_DISABLED : GLFW_CURSOR_NORMAL);
  75. }
  76. void Window::onKey(GLFWwindow* w, int key, int scancode, int action, int mods) {
  77. void* p = glfwGetWindowUserPointer(w);
  78. if(p != nullptr) {
  79. Window* rw = static_cast<Window*>(p);
  80. TextInput* input = rw->textInput;
  81. if(input != nullptr) {
  82. input->onKeyEvent(key, scancode, action, mods);
  83. }
  84. rw->buttons.onKey(key, scancode, action, mods);
  85. }
  86. }
  87. void Window::onChar(GLFWwindow* w, unsigned int codepoint) {
  88. void* p = glfwGetWindowUserPointer(w);
  89. if(p != nullptr) {
  90. TextInput* input = static_cast<Window*>(p)->textInput;
  91. if(input != nullptr) {
  92. input->onCharEvent(codepoint);
  93. }
  94. }
  95. }
  96. void Window::onResize(GLFWwindow* w, int width, int height) {
  97. void* p = glfwGetWindowUserPointer(w);
  98. if(p != nullptr) {
  99. Window* rw = static_cast<Window*>(p);
  100. rw->size.width = width;
  101. rw->size.height = height;
  102. }
  103. }
  104. void Window::onMouse(GLFWwindow* w, int button, int action, int mods) {
  105. void* p = glfwGetWindowUserPointer(w);
  106. if(p != nullptr) {
  107. static_cast<Window*>(p)->buttons.onMouse(button, action, mods);
  108. }
  109. }
  110. void Window::onMouseMove(GLFWwindow* w, double x, double y) {
  111. void* p = glfwGetWindowUserPointer(w);
  112. if(p != nullptr) {
  113. static_cast<Window*>(p)->buttons.onMouseMove(x, y);
  114. }
  115. }