2016-01-18 1 views
0

Я занимаюсь базовой java некоторое время, и недавно я попытался начать с LWJGL (Light Weight Java Game Library) на моем mac. Я правильно установил его для eclipse mars и создаю базовый план для программы, следуя некоторым онлайн-учебникам.LWJGL window on main thread

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; 
      } 
     } 
    } 
} 

Это слово в слово код из большинства учебников, и это, похоже, не работает для меня. Это говорит мне, что я делаю что-то не так с потоками, и я очень смущен. Я только смог найти это в другом месте, и все, что он сказал, переместило окно в основной поток, извините, что я немного новичок в потоковом, поэтому я тоже не знаю, как это сделать. Я получаю сообщение об ошибке, глядя, как это:

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 
) 

Все было бы очень полезно, я бегу Mac OSX Йосемити, Eclipse, Марс, и у меня есть LWJGL каждую ночь с 16-го января 2016 года

ответ

0

Причина, почему вы» re получение этой ошибки связано с тем, что вы запускаете окно GLFW в отдельном потоке. Запустите окно в основном потоке, и он будет работать.

Как прочитать в этой теме в комментариях Here

сделал быструю проверку. Создание более одного дисплея в одной и той же программе приводит к ошибке, даже если они создаются в отдельных потоках. Одна вещь, которую вы можете сделать, это создать раздельные программы Java для двух (или более) дисплеев, которые вам нужны, и они общаются с помощью сокетов и/или потоков

Это означает, что с помощью каких-либо нить кроме основной поток что приведет к ошибке.