2016-02-24 5 views
1

Я пытался использовать OpenGL, следуя инструкциям ThinMatrix. Единственное, что я делаю по-другому, - он использовал lwjgl 2, и я использую 3. Я думал, что это будет хороший вызов, и это определенно оказалось. Говорят, что никаких ограничений не было, но я уверен, что я их уже установил!Нет экземпляра GLCapabilities для текущего потока

В основном полная ошибка, я получаю

Exception in thread "main" java.lang.IllegalStateException: No GLCapabilities instance has been set for the current thread. 
at org.lwjgl.opengl.GL.getCapabilities(GL.java:211) 
at org.lwjgl.opengl.GL20.getInstance(GL20.java:378) 
at org.lwjgl.opengl.GL20.glCreateShader(GL20.java:464) 
at net.robharding.base.shaders.ShaderProgram.loadShader(ShaderProgram.java:67) 
at net.robharding.base.shaders.ShaderProgram.<init>(ShaderProgram.java:17) 
at net.robharding.base.shaders.StaticShader.<init>(StaticShader.java:9) 
at net.robharding.base.engine.Display.init(Display.java:77) 
at net.robharding.base.engine.Display.<init>(Display.java:31) 
at net.robharding.base.MainComponent.main(MainComponent.java:8) 

Для меня это не имеет никакого смысла, потому что я сделал GL.CreateCapabilities() ;, и я ничего не могу найти в Интернете об этой ошибке. ..

package net.robharding.base.engine; 
import org.lwjgl.glfw.*; 
import org.lwjgl.opengl.*; 

import net.robharding.base.shaders.StaticShader; 

import static org.lwjgl.glfw.GLFW.*; 
import static org.lwjgl.system.MemoryUtil.*; 

public class Display { 

    private String title; 
    private int width, height; 

    @SuppressWarnings("unused") 
    private GLFWErrorCallback errorCallback; 
    @SuppressWarnings("unused") 
    private GLFWKeyCallback keyCallback; 

    private long windowID; 

    private Loader loader; 
    private Renderer renderer; 
    private StaticShader shader; 

    public Display(String title, int width, int height) { 
     this.title = title; 
     this.width = width; 
     this.height = height; 

     init(); 
    } 

    private void keyPressed(int key, int scancode, int mods) { 

    } 

    private void keyReleased(int key, int scancode, int mods) { 
     if(key == GLFW_KEY_ESCAPE) 
      glfwSetWindowShouldClose(windowID, GLFW_TRUE); 
    } 

    private void init() { 
     // Setup an error callback. The default implementation 
     // will print the error message in System.err. 
     glfwSetErrorCallback(errorCallback = GLFWErrorCallback.createPrint(System.err)); 

     if(glfwInit() != GLFW_TRUE) 
      throw new IllegalStateException("Unable to initialize GLFW"); 

     glfwDefaultWindowHints(); 
     glfwWindowHint(GLFW_VISIBLE, GLFW_TRUE); 
     glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); 

     windowID = glfwCreateWindow(width, height, title, NULL, NULL); 
     if(windowID == NULL) 
      throw new RuntimeException("Failed to create the GLFW window"); 

     glfwSetKeyCallback(windowID, keyCallback = new GLFWKeyCallback() { 
      @Override 
      public void invoke(long window, int key, int scancode, int action, int mods) { 
       if(action == GLFW_PRESS) 
        keyPressed(key, scancode, mods); 
       else if(action == GLFW_RELEASE) 
        keyReleased(key, scancode, mods); 
      } 
     }); 

     GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor()); 
     glfwSetWindowPos(windowID, (vidmode.width() - width)/2, (vidmode.height() - height)/2); 

     glfwMakeContextCurrent(windowID); 
     glfwSwapInterval(1); 

     loader = new Loader(); 
     renderer = new Renderer(); 
     shader = new StaticShader(); 

     glfwShowWindow(windowID); 
    } 

    public void run() { 
     GL.createCapabilities(); 

     GL11.glViewport(0, 0, width, height); 

     float[] vertices = { 
       -0.5f, 0.5f, 0, // V1 
       -0.5f, -0.5f, 0, // V2 
       0.5f, -0.5f, 0, // V3 
       0.5f, 0.5f, 0 // V4 
     }; 

     int[] indices = { 
       0, 1, 3, 
       3, 2, 1 
     }; 

     RawModel model = loader.loadToVAO(vertices, indices); 

     while(glfwWindowShouldClose(windowID) == GLFW_FALSE) { 
      renderer.prepare(); 

      shader.start(); 
      renderer.render(model); 
      shader.stop(); 

      glfwSwapBuffers(windowID); 

      glfwPollEvents(); 
     } 

     shader.cleanUp(); 
     loader.cleanUp(); 
    } 

} 

Вот этот метод, по которому он возвращается.

private static int loadShader(String file, int type) { 
    StringBuilder shaderSource = new StringBuilder(); 
    try { 
     BufferedReader reader = new BufferedReader(new FileReader(file)); 
     String line; 
     while((line = reader.readLine()) != null) { 
      shaderSource.append(line).append("\n"); 
     } 
     reader.close(); 
    } catch(IOException e) { 
     System.err.print("Count not read file!"); 
     e.printStackTrace(); 
     System.exit(-1); 
    } 

    int shaderID = GL20.glCreateShader(type); 
    GL20.glShaderSource(shaderID, shaderSource); 
    GL20.glCompileShader(shaderID); 
    if(GL20.glGetShaderi(shaderID, GL20.GL_COMPILE_STATUS) == GL11.GL_FALSE) { 
     System.out.println(GL20.glGetShaderInfoLog(shaderID, 500)); 
     System.err.println("Could not compile shader!"); 
     System.exit(-1); 
    } 
    return shaderID; 
} 

ответ

1

Ваш код пытается использовать OpenGL перед созданием контекста.

Метод init, в котором создается шейдер, вызывается в конструкторе, но контекст создается в начале метода run. Чтобы решить эту проблему, переместите вызов метода init на метод run после GL.createCapabilities();.

Также обратите внимание, что контексты OpenGL всегда связаны только с одним потоком. Поэтому все команды OpenGL должны быть выпущены из этого одного потока.

+0

Глупо меня. Исправлено: D Спасибо –

Смежные вопросы