Window.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  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. glfwSetWindowUserPointer(window, this);
  42. glfwSetKeyCallback(window, onKey);
  43. glfwSetCharCallback(window, onChar);
  44. glfwSetFramebufferSizeCallback(window, onResize);
  45. glfwSetMouseButtonCallback(window, onMouse);
  46. glfwSetCursorPosCallback(window, onMouseMove);
  47. glfwMakeContextCurrent(window);
  48. glfwSwapInterval(options.vsync);
  49. if(glewCounter == 0) {
  50. GLenum err = glewInit();
  51. if(err != GLEW_OK) {
  52. Error error;
  53. error.message.clear()
  54. .append("could not initialize GLEW: ")
  55. .append(glewGetErrorString(err));
  56. return error;
  57. }
  58. }
  59. glewCounter++;
  60. return {};
  61. }
  62. const Clock& Window::getFrameClock() const {
  63. return fps;
  64. }
  65. const Clock& Window::getTickClock() const {
  66. return tps;
  67. }
  68. const Size& Window::getSize() const {
  69. return size;
  70. }
  71. void Window::trapCursor(bool trap) {
  72. glfwSetInputMode(window, GLFW_CURSOR,
  73. trap ? GLFW_CURSOR_DISABLED : GLFW_CURSOR_NORMAL);
  74. }
  75. void Window::onKey(GLFWwindow* w, int key, int scancode, int action, int mods) {
  76. void* p = glfwGetWindowUserPointer(w);
  77. if(p != nullptr) {
  78. Window* rw = static_cast<Window*>(p);
  79. TextInput* input = rw->textInput;
  80. if(input != nullptr) {
  81. input->onKeyEvent(key, scancode, action, mods);
  82. }
  83. rw->buttons.onKey(key, scancode, action, mods);
  84. }
  85. }
  86. void Window::onChar(GLFWwindow* w, unsigned int codepoint) {
  87. void* p = glfwGetWindowUserPointer(w);
  88. if(p != nullptr) {
  89. TextInput* input = static_cast<Window*>(p)->textInput;
  90. if(input != nullptr) {
  91. input->onCharEvent(codepoint);
  92. }
  93. }
  94. }
  95. void Window::onResize(GLFWwindow* w, int width, int height) {
  96. void* p = glfwGetWindowUserPointer(w);
  97. if(p != nullptr) {
  98. Window* rw = static_cast<Window*>(p);
  99. rw->size.width = width;
  100. rw->size.height = height;
  101. }
  102. }
  103. void Window::onMouse(GLFWwindow* w, int button, int action, int mods) {
  104. void* p = glfwGetWindowUserPointer(w);
  105. if(p != nullptr) {
  106. static_cast<Window*>(p)->buttons.onMouse(button, action, mods);
  107. }
  108. }
  109. void Window::onMouseMove(GLFWwindow* w, double x, double y) {
  110. void* p = glfwGetWindowUserPointer(w);
  111. if(p != nullptr) {
  112. static_cast<Window*>(p)->buttons.onMouseMove(x, y);
  113. }
  114. }