Engine.java 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. package me.hammerle.snuviengine.api;
  2. import org.lwjgl.glfw.*;
  3. import org.lwjgl.opengl.*;
  4. import static org.lwjgl.glfw.Callbacks.*;
  5. import static org.lwjgl.glfw.GLFW.*;
  6. import static org.lwjgl.opengl.GL11.*;
  7. import static org.lwjgl.system.MemoryUtil.*;
  8. public abstract class Engine
  9. {
  10. private static final String VERSION = "0.0.1";
  11. public static final int TILE_SIZE = 16;
  12. public static final float SCALE = 2.0f;
  13. private long window;
  14. private int fpsIndex = 0;
  15. private final long[] fps = new long[100];
  16. private long fpsSum = 0;
  17. private double currentFps = 0;
  18. private int tpsIndex = 0;
  19. private final long[] tps = new long[100];
  20. private long tpsSum = 0;
  21. private double currentTps = 0;
  22. private long nanosPerTick = 10_000_000;
  23. public Engine()
  24. {
  25. }
  26. public final void run()
  27. {
  28. initGLFW();
  29. loop();
  30. glfwFreeCallbacks(window);
  31. glfwDestroyWindow(window);
  32. glfwTerminate();
  33. GLFWErrorCallback error = glfwSetErrorCallback(null);
  34. if(error != null)
  35. {
  36. error.free();
  37. }
  38. }
  39. private void initGLFW()
  40. {
  41. GLFWErrorCallback.createPrint(System.err).set();
  42. if(!glfwInit())
  43. {
  44. throw new IllegalStateException("Unable to initialize GLFW");
  45. }
  46. glfwDefaultWindowHints();
  47. glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
  48. glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
  49. window = glfwCreateWindow(Shader.getViewWidth(), Shader.getViewHeight(), "SnuviEngine " + VERSION, NULL, NULL);
  50. if(window == NULL)
  51. {
  52. throw new RuntimeException("Failed to create the GLFW window");
  53. }
  54. glfwSetKeyCallback(window, (w, key, scancode, action, mods) ->
  55. {
  56. if(action == GLFW_RELEASE)
  57. {
  58. KeyHandler.onKeyUpEvent(key);
  59. if(key == GLFW_KEY_ESCAPE)
  60. {
  61. glfwSetWindowShouldClose(window, true);
  62. }
  63. }
  64. else if(action == GLFW_PRESS)
  65. {
  66. KeyHandler.onKeyDownEvent(key);
  67. }
  68. });
  69. glfwSetFramebufferSizeCallback(window, (w, fwidth, fheight) ->
  70. {
  71. glViewport(0, 0, fwidth, fheight);
  72. Shader.setViewPort(fwidth, fheight);
  73. });
  74. //glfwSetWindowAspectRatio(window, 16, 9);
  75. glfwMakeContextCurrent(window);
  76. glfwSwapInterval(1);
  77. glfwShowWindow(window);
  78. }
  79. private void loop()
  80. {
  81. GL.createCapabilities();
  82. long lastFrame = System.nanoTime();
  83. long lastTick = System.nanoTime();
  84. long time;
  85. long lag = 0;
  86. Shader.init();
  87. init();
  88. while(!glfwWindowShouldClose(window))
  89. {
  90. glfwSwapBuffers(window);
  91. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  92. time = System.nanoTime();
  93. fpsSum -= fps[fpsIndex];
  94. fps[fpsIndex] = time - lastFrame;
  95. fpsSum += fps[fpsIndex];
  96. lag += fps[fpsIndex];
  97. fpsIndex = (fpsIndex + 1) % fps.length;
  98. lastFrame = time;
  99. currentFps = (1_000_000_000.0 * fps.length) / fpsSum;
  100. while(lag >= nanosPerTick)
  101. {
  102. lag -= nanosPerTick;
  103. time = System.nanoTime();
  104. tpsSum -= tps[tpsIndex];
  105. tps[tpsIndex] = time - lastTick;
  106. tpsSum += tps[tpsIndex];
  107. tpsIndex = (tpsIndex + 1) % tps.length;
  108. lastTick = time;
  109. currentTps = (1_000_000_000.0 * tps.length) / tpsSum;
  110. KeyHandler.tick();
  111. tick();
  112. }
  113. Shader.doTasks();
  114. renderTick();
  115. glfwPollEvents();
  116. }
  117. }
  118. public final void setNanosPerTick(long nanos)
  119. {
  120. nanosPerTick = nanos;
  121. }
  122. public final double getTps()
  123. {
  124. return currentTps;
  125. }
  126. public final double getFps()
  127. {
  128. return currentFps;
  129. }
  130. public abstract void init();
  131. public abstract void tick();
  132. public abstract void renderTick();
  133. }