java - 尚未为当前线程设置 GLCapability 实例

标签 java opengl lwjgl

我一直在按照 ThinMatrix 的教程尝试 OpenGL。我做的唯一不同的是他使用的是 lwjgl 2,而我使用的是 3。我认为这将是一个很好的挑战,而且事实证明确实如此。它说没有设置 glcapability,但我很确定我已经设置了它们!

基本上我得到的完整错误是

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.CreateCapability();,而且我在网上找不到任何有关此错误的信息...

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

最佳答案

在创建上下文之前,您的代码会尝试使用 OpenGL。

在构造函数中调用创建着色器的 init 方法,但上下文是在 run 方法的开头创建的。要解决此问题,请将 init 方法的调用移至 GL.createCapability(); 之后的 run 方法。

另请注意,OpenGL 上下文始终与一个线程相关联。因此所有 OpenGL 命令都必须从这一线程发出。

关于java - 尚未为当前线程设置 GLCapability 实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35602715/

相关文章:

c++ - 我可以将 openGL 缓冲区设置为按照与 OBJ 文件类似的原理工作吗?

c++ - Opengl GLM 观察奇怪的行为

java - lwjgl 导入输入类不起作用

java - Spring Autowiring 的bean导致空指针

java - com.sun.star.lang.IllegalArgumentException - 不支持的 URL <文件 :///

java - Rijndael AES、addRoundKey、异或十六进制字符串并将它们存储为字节

opengl - 仅使用存储在 GPU 内存中的 'count' 参数调用 glDrawArray

java - 制作合适的 Java 数独生成器的问题

java - OpenGL 3 (LWJGL) LookAt 矩阵混淆

java - 如何存储从mysql检索到的数据并在java中显示为用户搜索的结果