GameClient.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. #include <iostream>
  2. #include <GL/glew.h>
  3. #include <GLFW/glfw3.h>
  4. #include <unordered_map>
  5. #include "GameClient.h"
  6. #include "common/utils/Types.h"
  7. #include "client/Keys.h"
  8. struct InternGameClient
  9. {
  10. ~InternGameClient()
  11. {
  12. if(window != nullptr)
  13. {
  14. glfwDestroyWindow(window);
  15. }
  16. if(glfwInitDone)
  17. {
  18. glfwTerminate();
  19. }
  20. }
  21. bool glfwInitDone = false;
  22. GLFWwindow* window = nullptr;
  23. };
  24. static const u64 NANOS_PER_TICK = 50000000;
  25. static const float lagFactor = 1.0f / NANOS_PER_TICK;
  26. static u64 timeFactor = 1;
  27. static int width = 0;
  28. static int height = 0;
  29. static InternGameClient client;
  30. static Keys keys;
  31. static bool initGLFW()
  32. {
  33. client.glfwInitDone = glfwInit();
  34. if(!client.glfwInitDone)
  35. {
  36. std::cout << "could not initialize GLFW\n";
  37. return true;
  38. }
  39. timeFactor = 1000000000 / glfwGetTimerFrequency();
  40. return false;
  41. }
  42. static bool initWindow(int w, int h, const char* windowName)
  43. {
  44. width = w;
  45. height = h;
  46. glfwDefaultWindowHints();
  47. glfwWindowHint(GLFW_VISIBLE, 0);
  48. glfwWindowHint(GLFW_RESIZABLE, 1);
  49. glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
  50. glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
  51. glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
  52. client.window = glfwCreateWindow(width, height, windowName, nullptr, nullptr);
  53. if(client.window == nullptr)
  54. {
  55. std::cout << "could not create window\n";
  56. return true;
  57. }
  58. glfwMakeContextCurrent(client.window);
  59. glfwSwapInterval(1);
  60. return false;
  61. }
  62. static bool initGLEW()
  63. {
  64. GLenum err = glewInit();
  65. if(err != GLEW_OK)
  66. {
  67. std::cout << "could not initialize GLEW: " << glewGetErrorString(err) << "\n";
  68. return true;
  69. }
  70. std::cout << "using GLEW " << glewGetString(GLEW_VERSION) << "\n";
  71. return false;
  72. }
  73. static void initCallbacks()
  74. {
  75. // GLFWwindow* w, int key, int scancode, int action, int mod
  76. glfwSetKeyCallback(client.window, [](GLFWwindow*, int key, int, int action, int)
  77. {
  78. if(action == GLFW_PRESS)
  79. {
  80. keys.press(key);
  81. }
  82. else if(action == GLFW_RELEASE)
  83. {
  84. keys.release(key);
  85. }
  86. });
  87. //glfwSetMouseButtonCallback(window, onMouseClick);
  88. //glfwSetFramebufferSizeCallback(window, onWindowResize);
  89. //glfwSetCursorPosCallback(window, onMouseMove);
  90. }
  91. static void tick()
  92. {
  93. std::cout << keys.down << std::endl;
  94. keys.tick();
  95. }
  96. static void renderTick(float /*lag*/)
  97. {
  98. }
  99. static u64 getTimeNanos()
  100. {
  101. return glfwGetTimerValue() * timeFactor;
  102. }
  103. static void loop()
  104. {
  105. u64 lastTime = getTimeNanos();
  106. u64 lag = 0;
  107. while(!glfwWindowShouldClose(client.window))
  108. {
  109. renderTick(lag * lagFactor);
  110. glfwSwapBuffers(client.window);
  111. u64 newTime = getTimeNanos();
  112. lag += newTime - lastTime;
  113. lastTime = newTime;
  114. while(lag >= NANOS_PER_TICK)
  115. {
  116. lag -= NANOS_PER_TICK;
  117. tick();
  118. }
  119. glfwPollEvents();
  120. }
  121. }
  122. void GameClient::start(int w, int h, const char* windowName)
  123. {
  124. if(initGLFW() || initWindow(w, h, windowName) || initGLEW())
  125. {
  126. return;
  127. }
  128. initCallbacks();
  129. glfwShowWindow(client.window);
  130. loop();
  131. }
  132. /*#include <iostream>
  133. #include <cmath>
  134. #include "client/GameClient.h"
  135. #include "common/block/Blocks.h"
  136. #include "client/rendering/block/BlockRenderers.h"
  137. #include "client/rendering/entity/EntityRenderer.h"
  138. #include "client/rendering/gui/StartMenu.h"
  139. using namespace std;
  140. GameClient::GameClient()
  141. {
  142. BlockRegistry::registerBlocks();
  143. BlockRenderers::init();
  144. keyManager.map(KEY_LEFT, GLFW_KEY_A);
  145. keyManager.map(KEY_RIGHT, GLFW_KEY_D);
  146. keyManager.map(KEY_UP, GLFW_KEY_W);
  147. keyManager.map(KEY_DOWN, GLFW_KEY_S);
  148. keyManager.map(KEY_JUMP, GLFW_KEY_SPACE);
  149. keyManager.map(KEY_SNEAK, GLFW_KEY_LEFT_SHIFT);
  150. keyManager.map(KEY_TEST, GLFW_KEY_T);
  151. mouseManager.map(MOUSE_LEFT, GLFW_MOUSE_BUTTON_1);
  152. activeGUI = new StartMenu();
  153. }
  154. GameClient::~GameClient()
  155. {
  156. if(activeGUI != nullptr)
  157. {
  158. delete activeGUI;
  159. }
  160. }
  161. void GameClient::tick()
  162. {
  163. tps.update();
  164. diffMouseY = 0;
  165. diffMouseX = 0;
  166. mouseManager.tick();
  167. keyManager.tick();
  168. if(activeGUI != nullptr)
  169. {
  170. GUI* newGUI = activeGUI->tick(keyManager, mouseManager);
  171. if(newGUI != activeGUI)
  172. {
  173. delete activeGUI;
  174. activeGUI = newGUI;
  175. }
  176. }
  177. }
  178. void GameClient::render3DTick(float lag)
  179. {
  180. fps.update();
  181. }
  182. void GameClient::render2DTick(float lag)
  183. {
  184. if(activeGUI != nullptr)
  185. {
  186. activeGUI->render2DTick(shader, directRenderer, lag);
  187. }
  188. Engine::setMixMode();
  189. shader.setToIdentity();
  190. shader.updateModelMatrix();
  191. string wusi;
  192. wusi = "FPS: " + to_string(fps.getUpdatesPerSecond());
  193. float y = directRenderer.drawString(10, 10, true, wusi);
  194. wusi = "TPS: " + to_string(tps.getUpdatesPerSecond());
  195. directRenderer.drawString(10, y, true, wusi);
  196. }
  197. void GameClient::onKeyEvent(int key, int scancode, int action, int mods)
  198. {
  199. if(action == GLFW_PRESS)
  200. {
  201. keyManager.press(key);
  202. }
  203. else if(action == GLFW_RELEASE)
  204. {
  205. keyManager.release(key);
  206. }
  207. }
  208. double GameClient::transformMouse(double x)
  209. {
  210. if(x >= -MOUSE_BORDER && x <= MOUSE_BORDER)
  211. {
  212. return x * x * x;
  213. }
  214. else if(x >= MOUSE_BORDER)
  215. {
  216. const double k = (3 * MOUSE_BORDER * MOUSE_BORDER);
  217. const double y = MOUSE_BORDER * MOUSE_BORDER * MOUSE_BORDER;
  218. const double d = y - k * MOUSE_BORDER;
  219. return k * x + d;
  220. }
  221. else
  222. {
  223. const double k = (3 * MOUSE_BORDER * MOUSE_BORDER);
  224. const double y = -MOUSE_BORDER * MOUSE_BORDER * MOUSE_BORDER;
  225. const double d = y - k * MOUSE_BORDER;
  226. return k * x + d;
  227. }
  228. }
  229. void GameClient::onMouseMove(double x, double y)
  230. {
  231. if(mouseTrapped)
  232. {
  233. diffMouseX = transformMouse(oldMouseX - x) * (1 / (MOUSE_BORDER * MOUSE_BORDER * 3));
  234. diffMouseY = transformMouse(oldMouseY - y) * (1 / (MOUSE_BORDER * MOUSE_BORDER * 3));
  235. oldMouseX = x;
  236. oldMouseY = y;
  237. }
  238. }
  239. void GameClient::onMouseClick(int button, int action, int mods)
  240. {
  241. if(action == GLFW_PRESS)
  242. {
  243. mouseManager.press(button);
  244. }
  245. else if(action == GLFW_RELEASE)
  246. {
  247. mouseManager.release(button);
  248. }
  249. }*/