简体   繁体   中英

LWJGL 3 - GLFW Window crash

So, I am pretty new to LWJGL and GLFW, and I'm following a tutorial. I'm on MacOS Big Sur 11.5.2 the window does stay open but crashes immediately and doesn't show. Anyone know why this is happening? Tutorial: click here LWJGL Version: 3.2.2 JDK: JavaSE-1.8

Window.java:

package com.bmc.voxel3d;

import org.lwjgl.glfw.GLFW;
import org.lwjgl.glfw.GLFWVidMode;

public class Window {
    private int width, height;
    private String title;
    private long window;
    
    public Window(int width, int height, String title) {
        this.width = width;
        this.height = height;
        this.title = title;
    }
    
    public void create() {
        if(!GLFW.glfwInit()) {
            System.out.println("ERROR: Didn't initialize GLFW.");
            return;
        }
        
        window = GLFW.glfwCreateWindow(width, height, title, 0, 0);
        
        if(window == 0) {
            System.out.println("ERROR: Could not make window.");
            return;
        }
        
        GLFWVidMode videoMode = GLFW.glfwGetVideoMode(GLFW.glfwGetPrimaryMonitor());
        GLFW.glfwSetWindowPos(window, (videoMode.width() - width) / 2, (videoMode.height() - height / 2));
        GLFW.glfwShowWindow(window);
    }
}

and Main.java:

package com.bmc.minecraft;

import com.bmc.voxel3d.Window;

public class Main implements Runnable{
    public Thread game;
    public static Window window;
    public static final int WIDTH = 854, HEIGHT = 480;
    
    public void start() {
        game = new Thread(this, "game");
        game.start();
    }
    
    public static void init() {
        System.out.println("Initializing Game!");
        window = new Window(WIDTH, HEIGHT, "Game");
        window.create();
    }
    
    public void run() {
        init();
        while(true) {
            update();
            render();
        }
    }
    
    private void update() {
        System.out.println("Updating Game!");
    }
    
    private void render() {
        System.out.println("Rendering Game!");
    }
    
    public static void main(String[] args){
        new Main().start();
    }
}

Also, I have -XstartOnFirstThread in the Run Configuration Eclipse 2019

Most of GLFW's methods must be called on the main thread . You however are spawning a new thread (in Main::start ) and use that new thread to call GLFW methods.

The main thread is the thread which initially calls the public static void main(String[] args) method.

In your case, the only thing the main thread is doing is to spawn a new thread and then lay dormant until the JVM exits. There is no reason to spawn a new thread, since everything could've been handled by the main thread in this scenario as well. And in fact, if you want to call GLFW functions/methods in a cross-platform fashion also supporting macOS, then you must call GLFW initialization and windowing-related methods (like glfwInit , glfwCreateWindow , glfwPollEvents , ...) on the main thread.

See GLFW's documentation about which functions must be called from the main thread and which functions can be called from any thread. Example: https://www.glfw.org/docs/3.3/group__init.html#ga317aac130a235ab08c6db0834907d85e

Thread safety

This function must only be called from the main thread.

In order to fix your code, you could modify your Main class to the following (not spawning a new thread):

package com.bmc.minecraft;
import com.bmc.voxel3d.Window;
public class Main {
  public static final int WIDTH = 854, HEIGHT = 480;
  public Window window;
  private void init() {
    System.out.println("Initializing Game!");
    window = new Window(WIDTH, HEIGHT, "Game");
    window.create();
  }
  private void start() {
    init();
    while(true) {
      update();
      render();
    }
  }
  private void update() {
    System.out.println("Updating Game!");
  }
  private void render() {
    System.out.println("Rendering Game!");
  }
  public static void main(String[] args){
    new Main().start();
  }
}

You must also poll window event messages with glfwPollEvents() as otherwise the OS will flag your window as unresponsive and it will likely not be resizable/draggable or even not show at all (on some platforms).

So add a call to glfwPollEvents() eg in your update method.

I assume that you mean that the window is not responding to user input.

The solution is fairly simple, instead of true in the game loop, you need to put !glfwWindowShouldClose(window) , which will tell GLFW that it should close when the x button is pressed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM