在MAC OS下解决GLFW问题

时间:2017-06-21 15:23:38

标签: java macos lwjgl glfw

我必须在Mac上运行java lwjgl游戏,但GLFW存在问题。

> Exception in thread "main" java.lang.ExceptionInInitializerError
at org.lwjgl.glfw.GLFW.glfwShowWindow(GLFW.java:1612)
at assignment7.windowmanager.Window.init(Window.java:65)
at assignment7.windowmanager.Window.start(Window.java:74)
at assignment7.windowmanager.Window.<init>(Window.java:35)
at assignment7.windowmanager.MyWindow.<init>(MyWindow.java:20)
at assignment7.MainGameLoop7.main(MainGameLoop7.java:14)

引起:java.lang.IllegalStateException:请使用-XstartOnFirstThread运行JVM。     在org.lwjgl.system.macosx.EventLoop。(EventLoop.java:17)     ......还有6个

这是我的错误代码

windows类的实现:

package assignment7.windowmanager;

import assignment7.entitites.Scene;
import assignment7.utilities.Input;
import org.lwjgl.opengl.GL;

import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.system.MemoryUtil.NULL;

import java.awt.Dimension;



/**
 * Created by Dennis Dubbert on 06.09.16.
 */
public abstract class Window {
    protected int   width, height;
    protected long  window;

    /*
     * In ScreenSize wird die Gr��e des aktuellen Bildschirms abgespeichert.
     * Daraufhin wird die initiale x- und y-Koordinate auf die Mitte des Bildschirmes gesetzt.
     * Da aber die linkere obere Ecke des Fensters zentriert w�re und nicht die Mitte dessen, 
     * wurde 320 von der x-Koordinate und 240 von der y-Koordinate abgezogen. (was der H�lfte des Fensters entspricht. Siehe MyWindow.java)
     */
    protected Dimension ScreenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
    protected int xWindowPos = (int) ScreenSize.getWidth()/2 - 320;
    protected int yWindowPos = (int) ScreenSize.getHeight()/2 - 240;

    public Window(int width, int height) {
        this.width = width;
        this.height = height;
        start();
    }

    private void init(){
        if(glfwInit() != GL_TRUE){
            System.err.println("Could not initialize our glfw!");
            return;
        }

        glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
        glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
        glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);

        window = glfwCreateWindow(width, height, "assignment7", NULL, NULL);

        glfwSetWindowPos(window, 80, 30);


        if(window == NULL){
            System.err.println("Could not create our Window!");
            return;
        }




        Input.init(window, this);
        glfwMakeContextCurrent(window);
        //here is one Error
        glfwShowWindow(window);

        GL.createCapabilities();

        System.out.println("Your OpenGL version is " + glGetString(GL_VERSION));
        onInit();
    }

    public void start(){
        init();

        while(true){

            update();
            render();

            if(glfwWindowShouldClose(window) == GL_TRUE){
                break;
            }
        }

        glfwDestroyWindow(window);
        glfwTerminate();
    }

    private void update(){
        //here is an Error, too
        glfwPollEvents();
        onUpdate(glfwGetTime());
    }

    private void render(){
        if(Scene.getAmountOfCollisions() == 5){
            glfwDestroyWindow(window);
            glfwTerminate();
            System.exit(1);
        }
        onRender();
        glfwSwapBuffers(window);
    }

    public void moveWindowPos(int x, int y){

        /*
         * Um das leichte ruckeln zu entfernen k�nnte man statt einmal um 1 zu erh�hen/erniedrigen 10 mal um 0.1f erh�hen/erniedrigen.
         * Gedanke dahinter: die Taktrate der GPU ist um einiges Schneller als die einfache erh�hung um 1. 
         * Erste Idee (noch falsch!): 
         * if( x < 0 ){
            for(float i = x; i < 0; i++){
                glfwSetWindowPos(window, xWindowPos-=0.1f, yWindowPos);
                }
            }
        if( x > 0 ){
            for(float i = 0; i < x; i++){
                glfwSetWindowPos(window, xWindowPos+=0.1f, yWindowPos);
            }
        }
        if( y < 0 ){
            for(float i = y; i < 0; i++){
                glfwSetWindowPos(window, xWindowPos, yWindowPos-=0.1f);
            }
        }
        if( y > 0 ){
            for(float i = 0; i < y; i++){
                glfwSetWindowPos(window, xWindowPos, yWindowPos+=0.1f);
            }
        }
         */
                xWindowPos = xWindowPos+x;
                yWindowPos = yWindowPos+y;
                glfwSetWindowPos(window, xWindowPos, yWindowPos);

    }

    protected abstract void onInit();
    protected abstract void onUpdate(double currentTime);
    protected abstract void onRender();
    public abstract void onResize(int width, int height);
    public abstract void onKeyboard(float cursorPositionX, float       cursorPositionY, int pressedKey, int mods);
    public abstract void onMouse(float cursorPositionX, float cursorPositionY, int button, int action);

}

也许你可以帮助我

2 个答案:

答案 0 :(得分:2)

从上面发布的错误看来,您只需要将-XstartOnFirstThread添加到用于运行程序的命令中。所以它应该是这样的。

java -XstartOnFirstThread -jar executable.jar

如果您使用的是ide,则必须编辑运行配置以包含此参数。

发生此错误是因为您的帧管理必须在应用程序的主线程中完成。另外,要小心,因为很多GLFW命令只能从主线程调用。您可以在每个命令的文档中(在注释部分中)确定这适用于哪些。 example

答案 1 :(得分:1)

您只需在Eclipse中配置运行配置, 像这样:

first choose the run configuration

paste the -XstartOnFirstThread to the run argument

然后点击“运行”,您将不再看到此例外。