OpenGL 在编码着色器时找不到上下文。: LWJGL

OpenGL doesn't find context while coding shaders.: LWJGL

我在 lwjgl 上,只是在编写我的引擎,因为我要将它重新用于其他项目。但是当我对我的着色器进行编码和测试时,它给出了这个错误。

FATAL ERROR in native method: Thread[main,5,main]: No context is current or a function that is not available in the current context was called. The JVM will abort execution.
    at org.lwjgl.opengl.GL20C.glCreateShader(Native Method)
    at org.lwjgl.opengl.GL20.glCreateShader(GL20.java:253)
    at bengine.shaders.ShaderProgram.loadShader(ShaderProgram.java:51)
    at bengine.shaders.ShaderProgram.<init>(ShaderProgram.java:13)
    at bengine.shaders.StaticShader.<init>(StaticShader.java:10)
    at Main.jav.init(jav.java:53)
    at bengine.window.CustomWindow.gameloop(CustomWindow.java:54)
    at bengine.window.WindowRunner.runWindow(WindowRunner.java:7)
    at Main.jav.main(jav.java:59)

Process finished with exit code 1

我需要答案,请务必给出答案,并说明这是否已被关闭。

这是我的代码:

ShaderProgram.java:

package bengine.shaders;

import org.lwjgl.opengl.GL20;

import java.io.*;

public abstract class ShaderProgram {
    private int shadersID;
    private int vertexShaderID;
    private int fragmentShaderID;

    public ShaderProgram(String vertFile, String fragFile) {
        vertexShaderID = ShaderProgram.loadShader(vertFile, GL20.GL_VERTEX_SHADER);
        fragmentShaderID = ShaderProgram.loadShader(fragFile, GL20.GL_FRAGMENT_SHADER);
        shadersID = GL20.glCreateProgram();
        GL20.glAttachShader(shadersID, vertexShaderID);
        GL20.glAttachShader(shadersID, fragmentShaderID);
        GL20.glLinkProgram(shadersID);
        GL20.glValidateProgram(shadersID);
    }

    public void start() { GL20.glUseProgram(shadersID); }
    public void stop() { GL20.glUseProgram(0); }
    public void clear() {
        stop();
        GL20.glDetachShader(shadersID, vertexShaderID);
        GL20.glDetachShader(shadersID, fragmentShaderID);
        GL20.glDeleteShader(vertexShaderID);
        GL20.glDeleteShader(fragmentShaderID);
        GL20.glDeleteProgram(shadersID);
    }

    protected void bindAttribute(int attribute, String variableName) {
        GL20.glBindAttribLocation(shadersID, attribute, variableName);
    }

    protected abstract void bindAttributes();

    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");
            }
        } catch(IOException e) {
            e.printStackTrace();
        }

        int shaderID = GL20.glCreateShader(type);
        GL20.glShaderSource(shaderID, shaderSource);
        GL20.glCompileShader(shaderID);
        return shaderID;
    }
}

StaticShader.java:

package bengine.shaders;

import org.lwjgl.glfw.GLFW;

public class StaticShader extends ShaderProgram {
    private static final String VERTEX_FILE = "src/bengine/shaders/vertShader.glsl";
    private static final String FRAGMENT_FILE = "src/bengine/shaders/fragmentShader.glsl";

    public StaticShader() {
        super(VERTEX_FILE, FRAGMENT_FILE);
    }

    @Override
    protected void bindAttributes() {
        super.bindAttribute(0, "position");
    }
}

两个着色器:

fragment shader:

#version 400 core

in vec3 colour;
out vec4 col;

void main(void) {
    col = vec4(colour, 1.0);
}

vertex shader:

#version 400 core

in vec3 position;
out vec3 colour;

void main(void) {
    gl_Position = vec4(position, 1.0);

    colour = vec3(position.x, position.y, position.z);
}

还有 window.

package bengine.window;

import bengine.math.Vector4;
import bengine.shaders.ShaderProgram;
import bengine.shaders.StaticShader;
import org.lwjgl.opengl.GL;
import org.lwjgl.opengl.GL11;

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

public abstract class CustomWindow {
    private long window;
    public StaticShader shader;
    public CustomWindow(int w, int h, String name) {
        if(!glfwInit()) {
            System.err.println("Bengi engine failure: GLFW initialization failed, this is a internal error, can't be fixed.");
        }

        glfwDefaultWindowHints();
        this.window = glfwCreateWindow(w, h, name, 0, 0);

        if(this.window == 0) {
            System.err.println("Bengi engine failure: Window is 0.");
        }

        System.out.println("Window created.");

        glfwMakeContextCurrent(window);

        System.out.println("Context was made.");
    }

    public abstract void render();
    public abstract void update();
    public abstract void init();

    public void swapBuffers() {
        glfwSwapBuffers(this.window);
    }

    public void enableGLClearWith(int mode, Vector4 color) {
        GL11.glClearColor(color.getX(), color.getY(), color.getZ(), color.getW());
        GL11.glClear(mode);
    }

    public void runTask(Task task) {
        task.runTask();
    }

    protected void gameloop() {
        glfwInit(); // to avoid null pointer
        //glfwMakeContextCurrent(window);

        init();

        GL.createCapabilities(true);

        while(!glfwWindowShouldClose(this.window)) {
            //swapBuffers();
            render();
            update();

            glfwPollEvents();
        }
    }
}

Main.java:

package Main;

import bengine.math.Vector4;
import bengine.window.*;
import bengine.CONSTANTS;

import bengine.window.WindowRunner;
import bengine.math.Vector3;
import bengine.renderer.Mesh;
import bengine.renderer.Renderer;
import bengine.renderer.Vertex;
import bengine.shaders.StaticShader;
//import org.lwjgl.opengl.GL11;

public class jav {
    public static CustomWindow window;

    public static void main(String[] args) {
        Mesh mesh = new Mesh(
                new Vertex[] {
                        new Vertex(new Vector3(-0.5f, -0.5f, -0.5f)),
                        new Vertex(new Vector3(-0.5f, 0.5f, -0.5f)),
                        new Vertex(new Vector3(0.5f, -0.5f, -0.5f)),
                        new Vertex(new Vector3(0.5f, 0.5f, -0.5f)),
                        new Vertex(new Vector3(0.0f, 0.6f, -0.5f)),
                },

                new int[] {
                        0, 1, 2, 1, 3, 2, 1, 4, 3
                }
        );

        Renderer renderer = new Renderer();

        window = new CustomWindow(1200, 800, "hello world") {
            @Override
            public void render() {
                swapBuffers();

                enableGLClearWith(CONSTANTS.COLOR, new Vector4(0f, 0f, 0f, 1f));
                shader.start();
                renderer.renderMesh(mesh, CONSTANTS.TRI_RENDER);
                shader.stop();
            }

            @Override
            public void update() {

            }

            @Override
            public void init() {
                shader = new StaticShader();
            }
        };

        WindowRunner runner = new WindowRunner();

        runner.runWindow(window);
    }
}

和 window 跑步者(稍后弃用)

package bengine.window;

import org.jetbrains.annotations.NotNull;

public class WindowRunner {
    public static void runWindow(@NotNull CustomWindow window) {
        window.gameloop();
    }
}

我不知道为什么会这样,渲染器中的所有其他包和其他包都有上下文。请回答。

GL.createCapabilities(true); 必须在 init() 之前调用。注释中是一个抽象方法。它被覆盖并在 init 中构造 StaticShader 对象。所以必须提前保证OpenGL能力:

protected void gameloop() {
    
    GL.createCapabilities(true);
    init();

    while(!glfwWindowShouldClose(this.window)) {
        //swapBuffers();
        render();
        update();

        glfwPollEvents();
    }
}