123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- package me.hammerle.snuviengine.api;
- import org.lwjgl.glfw.*;
- import org.lwjgl.opengl.*;
- import static org.lwjgl.glfw.GLFW.*;
- import static org.lwjgl.opengl.GL11.*;
- import static org.lwjgl.system.MemoryUtil.*;
- public final class Window {
- private final double secondsPerTick;
- private long window = NULL;
- private Keys keys = null;
- private Gamepad gamepad = null;
- private Renderer renderer;
- private final Stats stats = new Stats();
- public Window(long nanosPerTick) {
- secondsPerTick = nanosPerTick / 1_000_000_000.0;
- }
- public boolean initialize(String name, int width, int height) {
- setErrorCallback();
- if(initializeGLFW()) {
- return false;
- }
- setWindowHints();
- if(createWindow(name, width, height)) {
- return false;
- }
- setKeyCallback();
- setGamepad();
- setResizeCallback();
- createAndSetContext();
- setBufferSwapInterval();
- return !initializeRenderer(width, height);
- }
- private void setErrorCallback() {
- GLFWErrorCallback.createPrint(System.out).set();
- }
- private boolean initializeGLFW() {
- return !glfwInit();
- }
- private void setWindowHints() {
- glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
- glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
- glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
- }
- private boolean createWindow(String name, int width, int height) {
- window = glfwCreateWindow(width, height, name, NULL, NULL);
- if(window == NULL) {
- terminateGLFW();
- return true;
- }
- return false;
- }
- private void terminateGLFW() {
- glfwTerminate();
- }
- private void setKeyCallback() {
- keys = new Keys();
- glfwSetKeyCallback(window, (eventWindow, key, scancode, action, mods) -> {
- if(action == GLFW_PRESS) {
- keys.press(key);
- } else if(action == GLFW_RELEASE) {
- keys.release(key);
- }
- });
- }
- private void setGamepad() {
- gamepad = new Gamepad(GLFW_JOYSTICK_1);
- }
- private void setResizeCallback() {
- glfwSetFramebufferSizeCallback(window, (eventWindow, width, height) -> {
- glViewport(0, 0, width, height);
- renderer.setSize(width, height);
- });
- }
- private void createAndSetContext() {
- glfwMakeContextCurrent(window);
- GL.createCapabilities();
- }
- private void setBufferSwapInterval() {
- glfwSwapInterval(1);
- }
- private boolean initializeRenderer(int width, int height) {
- int shaderProgram = Shader.createShaderProgram("vertex.vs", "fragment.fs");
- if(shaderProgram == -1) {
- return true;
- }
- renderer = new Renderer(shaderProgram, width, height);
- return false;
- }
- public void open(Game game) {
- game.onCompleteInitialization(stats, keys, gamepad);
- runGameLoop(game);
- game.onStop();
- destroyWindow();
- terminateGLFW();
- freeErrorCallback();
- }
- private void runGameLoop(Game game) {
- double lastSecondTime = glfwGetTime();
- double lag = 0;
- while(!glfwWindowShouldClose(window) && game.isRunning()) {
- double newSecondTime = glfwGetTime();
- lag += newSecondTime - lastSecondTime;
- lastSecondTime = newSecondTime;
- while(lag >= secondsPerTick) {
- lag -= secondsPerTick;
- tick(game);
- }
- renderTick(game, (float) (lag / secondsPerTick));
- }
- }
- private void tick(Game game) {
- stats.updateTicksPerSecond();
- gamepad.tick();
- keys.tick();
- game.tick();
- }
- private void renderTick(Game game, float lag) {
- stats.updateFramesPerSecond();
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- game.renderTick(renderer, lag);
- glfwSwapBuffers(window);
- glfwPollEvents();
- }
- private void destroyWindow() {
- glfwDestroyWindow(window);
- }
- private void freeErrorCallback() {
- GLFWErrorCallback error = glfwSetErrorCallback(null);
- if(error != null) {
- error.free();
- }
- }
- }
|