lwjgl 3:没有为当前线程设置GLCapabilities实例。 glCreateProgram()

时间:2016-09-07 16:58:37

标签: java shader lwjgl

我无法解决有问题的问题。我尝试了几个解决这个错误的方法但没有任何积极的结果。如果我尝试删除glCreateProgram()方法,则错误转移到glCreateShader()方法。

错误

Exception in thread "main" java.lang.ExceptionInInitializerError
Caused by: java.lang.IllegalStateException: No GLCapabilities instance set for the current thread. Possible solutions:
    a) Call GL.createCapabilities() after making a context current in the current thread.
    b) Call GL.setCapabilities() if a GLCapabilities instance already exists for the current context.
    at org.lwjgl.opengl.GL.getCapabilities(GL.java:238)
    at org.lwjgl.opengl.GL20.glCreateProgram(GL20.java:209)
    at ms.shaders.ShaderProgram.<init>(ShaderProgram.java:18)
    at ms.shaders.Shaders.<init>(Shaders.java:8)
    at ms.renderer.Renderer.<init>(Renderer.java:13)
    at ms.main.MainGame.<clinit>(MainGame.java:16)

ShaderProgram

package ms.shaders;

import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL20.*;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public abstract class ShaderProgram {

    private int programID;
    private int vShaderID;
    private int fShaderID;

    public ShaderProgram(String vShader, String fShader)  {

        programID = glCreateProgram(); //Error line

        String vertexShaderSource = loadShader(vShader);

        vShaderID = glCreateShader(GL_VERTEX_SHADER);
        glShaderSource(vShaderID, vertexShaderSource);

        glCompileShader(vShaderID);

        if (glGetShaderi(vShaderID, GL_COMPILE_STATUS) == GL_FALSE) {
            throw new RuntimeException("Error creating vertex shader\n"
                    + glGetShaderInfoLog(vShaderID, glGetShaderi(vShaderID, GL_INFO_LOG_LENGTH)));
        }

        glAttachShader(programID, vShaderID);

        String fragmentShaderSource = loadShader(vShader);

        fShaderID = glCreateShader(GL_FRAGMENT_SHADER);
        glShaderSource(fShaderID, fragmentShaderSource);

        glCompileShader(fShaderID);

        if (glGetShaderi(fShaderID, GL_COMPILE_STATUS) == GL_FALSE) {
            throw new RuntimeException("Error creating vertex shader\n"
                    + glGetShaderInfoLog(fShaderID, glGetShaderi(fShaderID, GL_INFO_LOG_LENGTH)));
        }

        glAttachShader(programID, vShaderID);
    }

    protected abstract void bindAttribute();

    protected void bindAttribute(int attribute, String name) {
        glBindAttribLocation(programID, attribute, name);
    }

    public void link() {

        glLinkProgram(programID);

        if(glGetProgrami(programID, GL_LINK_STATUS) == GL_FALSE) {
            throw new RuntimeException("Failed to link program: ");
        }
    }

    public void validate() {

        glValidateProgram(programID);

        if(glGetShaderi(programID, GL_VALIDATE_STATUS) == GL_FALSE) {
            throw new RuntimeException("Failed to validate program: ");
        }
    }

    public void bind() {
        glUseProgram(programID);
    }

    public void unbind() {
        glUseProgram(0);
    }

    public void dispose() {

        unbind();

        glDetachShader(programID, vShaderID);
        glDetachShader(programID, fShaderID);
        glDeleteShader(vShaderID);
        glDeleteShader(fShaderID);
        glDeleteProgram(programID);
    }

    private static String loadShader(String file) {

        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){
            e.printStackTrace();
            System.exit(-1);
        }

        return shaderSource.toString();
    }
}

渲染

package ms.renderer;

import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL20.*;
import static org.lwjgl.opengl.GL30.*;

import ms.renderer.VertexArrayObject.Vertex;
import ms.shaders.Shaders;

public class Renderer {

    VertexArrayObject vertex = new VertexArrayObject();
    Shaders shaders = new Shaders();

    public void prepare() {

        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    }

    public void render(Vertex vertex) {

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        shaders.bind();

        glBindVertexArray(vertex.getVaoID());
        glEnableVertexAttribArray(0);

        glDrawElements(GL_TRIANGLES, vertex.getVertexCount(), GL_UNSIGNED_INT, 0);

        glDisableVertexAttribArray(0);
        glBindVertexArray(0);

        shaders.unbind();
    }

    public void clear() {

        shaders.dispose();
        vertex.cleanUp();
    }
}

MainGame

package ms.main;

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

import ms.input.KeyboardInput;
import ms.renderer.Renderer;
import ms.renderer.VertexArrayObject;
import ms.renderer.VertexArrayObject.Vertex;
import ms.utils.FinalVariables;

public class MainGame implements Runnable {

    private Thread thread;

    private static Display display = new Display();
    private static Renderer renderer = new Renderer();
    private static VertexArrayObject loader = new VertexArrayObject();

    private static int WIDTH = FinalVariables.WIDTH;
    private static int HEIGHT = FinalVariables.HEIGHT;
    private static String TITLE = FinalVariables.TITLE;

    private boolean isRunning = false;

    public static void main(String[] args) {

        MainGame game = new MainGame();

        display = new Display(WIDTH, HEIGHT, TITLE);
        game.start();
    }

    public void start() {

        isRunning = true;

        thread = new Thread(this, "MainThread");
        thread.start();
    }

    public void run() {

        display.init();
        display.libVersion();

        float[] positions = new float[]{

                -0.5f,  0.5f, 0.0f,
                -0.5f, -0.5f, 0.0f,
                 0.5f, -0.5f, 0.0f,
                 0.5f,  0.5f, 0.0f,
        };

        int[] indices = new int[]{

                0, 1, 3, 3, 1, 2

        };

        Vertex vertex = loader.loadToVAO(positions, indices);

        while(isRunning) {

            update();
            renderer.prepare();
            renderer.render(vertex);

            if(glfwWindowShouldClose(display.window)) {
                isRunning = false;
            }
        }

        renderer.clear();
    }

    public void update() {

        if(KeyboardInput.isKeyDown(GLFW_KEY_ESCAPE)) {
            isRunning = false;
        }

        glfwSwapBuffers(display.window);
        glfwPollEvents();
    }
}

显示我调用createCapabilities方法

package ms.main;

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

import org.lwjgl.glfw.GLFWKeyCallback;
import org.lwjgl.glfw.GLFWVidMode;

import ms.input.KeyboardInput;

public class Display {

    @SuppressWarnings("unused")
    private GLFWKeyCallback keyCallback;

    private int width;
    private int height;

    private String title;

    public long window;

    public Display() {

    }

    public Display(int width, int height, String title) {

        this.width = width;
        this.height = height;
        this.title = title;
    }

    public void init() {

        glfwInit();

        if(!glfwInit()) {
            System.err.println("Failed to initialize GLFW");
        }

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

        window = glfwCreateWindow(width, height, title, NULL, NULL);

        if(window == NULL) {
            System.err.println("Failed to create Window");
        }

        keyCallback = glfwSetKeyCallback(window, keyCallback = new KeyboardInput());

        GLFWVidMode vidMode = glfwGetVideoMode(glfwGetPrimaryMonitor());

        glfwSetWindowPos(window, 
                        (vidMode.width() - width) / 2, 
                        (vidMode.height() - height) / 2);

        glfwMakeContextCurrent(window);
        glfwSwapInterval(1);
        glfwShowWindow(window);

        createCapabilities();
    }

    public void libVersion() {

        System.out.println("LWJGL Version: " + glfwGetVersionString());
        System.out.println("OpenGL Version: " + glGetString(GL_VERSION));
    }

    public int getWidth() {
        return width;
    }

    public void setWidth(int width) {
        this.width = width;
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }
}

我认为问题出在createCapabilities()方法的位置,但我不知道如何解决。 说明我是初学者,现在我正在接近创建视频游戏。

提前感谢任何解决方案。

0 个答案:

没有答案