简体   繁体   中英

LWJGL window on main thread

I have been doing basic java for a while now, and I recently tried to start with LWJGL (Light Weight Java Game Library) on my mac. I installed it correctly for eclipse mars and am building a basic outline for a program by following some online tutorials.

package main;

import static org.lwjgl.glfw.GLFW.GLFW_RESIZABLE;
import static org.lwjgl.glfw.GLFW.glfwCreateWindow;
import static org.lwjgl.glfw.GLFW.glfwGetPrimaryMonitor;
import static org.lwjgl.glfw.GLFW.glfwGetVideoMode;
import static org.lwjgl.glfw.GLFW.glfwInit;
import static org.lwjgl.glfw.GLFW.glfwMakeContextCurrent;
import static org.lwjgl.glfw.GLFW.glfwPollEvents;
import static org.lwjgl.glfw.GLFW.glfwSetWindowPos;
import static org.lwjgl.glfw.GLFW.glfwShowWindow;
import static org.lwjgl.glfw.GLFW.glfwSwapBuffers;
import static org.lwjgl.glfw.GLFW.glfwWindowHint;
import static org.lwjgl.glfw.GLFW.glfwWindowShouldClose;
import static org.lwjgl.opengl.GL11.GL_TRUE;
import static org.lwjgl.system.MemoryUtil.NULL;

import java.nio.ByteBuffer;

import org.lwjgl.glfw.GLFWVidMode;

public class Main implements Runnable{

    private Thread thread;
    public boolean running = true;

    private long window;

    private int width = 1200, height = 800;

    public static void main(String args[]){
        Main game = new Main();
        game.start();
    }

    public void start(){
        running = true;
        thread = new Thread(this, "EndlessRunner");
        thread.start();
    }

    public void init(){
        // Initializes our window creator library - GLFW 
        // This basically means, if this glfwInit() doesn't run properlly
        // print an error to the console
        if(glfwInit() != GL_TRUE){
            // Throw an error.
            System.err.println("GLFW initialization failed!");
        }

        // Allows our window to be resizable
        glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);

        // Creates our window. You'll need to declare private long window at the
        // top of the class though. 
        // We pass the width and height of the game we want as well as the title for
        // the window. The last 2 NULL parameters are for more advanced uses and you
        // shouldn't worry about them right now.
        window = glfwCreateWindow(width, height, "Endless Runner", NULL, NULL);

        // This code performs the appropriate checks to ensure that the
        // window was successfully created. 
        // If not then it prints an error to the console
        if(window == NULL){
            // Throw an Error
            System.err.println("Could not create our Window!");
        }

        // creates a bytebuffer object 'vidmode' which then queries 
        // to see what the primary monitor is. 
        GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
        // Sets the initial position of our game window. 
        glfwSetWindowPos(window, 100, 100);
        // Sets the context of GLFW, this is vital for our program to work.
        glfwMakeContextCurrent(window);
        // finally shows our created window in all it's glory.
        glfwShowWindow(window);
    }

    public void update(){
        // Polls for any window events such as the window closing etc.
        glfwPollEvents();
    }

    public void render(){
        // Swaps out our buffers
        glfwSwapBuffers(window);
    }

    @Override
    public void run() {
        // All our initialization code
        init();
        // Our main game loop
        while(running){
            update();
            render();
            // Checks to see if either the escape button or the
            // red cross at the top were pressed.
            // if so sets our boolean to false and closes the
            // thread.
            if(glfwWindowShouldClose(window) == GL_TRUE){
                running = false;
            }
        }
    }
}

This is word for word the code from most tutorials and it doesn't seem to work for me. It tells me that I am doing something wrong with the threads and I am very confused. I was only able to find this at one other place and all it said was move the window to the main thread, sorry I am kinda new to threading so I don't really know how to do that either. I get an error report looking like this:

2016-01-18 12:09:36.761 java[21882:475722] *** Assertion failure in +[NSUndoManager _endTopLevelGroupings], /SourceCache/Foundation/Foundation-1153.20/Misc.subproj/NSUndoManager.m:340
2016-01-18 12:09:36.762 java[21882:475722] +[NSUndoManager(NSInternal) _endTopLevelGroupings] is only safe to invoke on the main thread.
2016-01-18 12:09:36.762 java[21882:475722] (
    0   CoreFoundation                      0x00007fff9160903c __exceptionPreprocess + 172
    1   libobjc.A.dylib                     0x00007fff91b8a76e objc_exception_throw + 43
    2   CoreFoundation                      0x00007fff91608e1a +[NSException raise:format:arguments:] + 106
    3   Foundation                          0x00007fff99e518cb -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 195
    4   Foundation                          0x00007fff99dd357f +[NSUndoManager(NSPrivate) _endTopLevelGroupings] + 156
    5   AppKit                              0x00007fff8cc0dc95 -[NSApplication run] + 756
    6   libglfw.dylib                       0x000000012944a17e initializeAppKit + 1342
    7   libglfw.dylib                       0x0000000129449845 _glfwPlatformCreateWindow + 37
    8   libglfw.dylib                       0x00000001294454b1 glfwCreateWindow + 513
    9   ???                                 0x000000011129e954 0x0 + 4582926676
    10  ???                                 0x0000000111290760 0x0 + 4582868832
    11  ???                                 0x0000000111290760 0x0 + 4582868832
    12  ???                                 0x0000000111290760 0x0 + 4582868832
    13  ???                                 0x0000000111290c4d 0x0 + 4582870093
    14  ???                                 0x0000000111290c92 0x0 + 4582870162
)

Anything would be very helpful, I run Mac OSX Yosemite, Eclipse Mars, and I have the LWJGL nightly from January 16th 2016

The reason why you're getting this error is because you are running the GLFW window on a separate thread. Run the window on the main thread and it'll work.

As read in this thread in the comments Here

Did a quick check. Creating more than one Display in the same program results in an error, even if they are created in seperate Threads. One thing you can do, is to create seperate java programs for the two (or more) displays that you need, and have them communicate using sockets and/or streams

Meaning that using any thread besides the main thread is going to result in an error.

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