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

huangapple go评论72阅读模式
英文:

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

问题

我在lwjgl上编写代码,正在为其他项目重用它。但在编写我的着色器并进行测试时,出现了以下错误。

本机方法的致命错误:线程[main,5,main]:没有当前上下文或调用了当前上下文中不可用的函数。JVM 将中止执行。
	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$1.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)

进程以退出代码 1 结束

这是我的代码:

ShaderProgram.java:

// ...(略去前面的内容)

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:

// ...(略去前面的内容)

// both shaders (glsl code)

CustomWindow.java:

// ...(略去前面的内容)

protected void gameloop() {
    glfwInit();
    init();

    GL.createCapabilities(true);

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

        glfwPollEvents();
    }
}

Main.java:

// ...(略去前面的内容)

public class jav {
    public static CustomWindow window;

    public static void main(String[] args) {
        Mesh mesh = new Mesh(
            // ...(略去内容)
        );

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

根据您提供的信息,我无法确认问题的具体原因,但根据错误消息,可能与OpenGL上下文的管理有关。请确保以下几点:

  1. 确保在同一线程上管理OpenGL上下文。在您的代码中,看起来您在CustomWindowgameloop方法中调用了glfwInit(),这可能会导致问题。通常情况下,应在主线程中初始化GLFW一次,然后在渲染循环中管理OpenGL上下文。

  2. 确保OpenGL的初始化和上下文管理在正确的顺序中进行。在CustomWindow的构造函数中,您应该首先调用glfwInit(),然后创建窗口,然后在gameloop方法中初始化OpenGL上下文。

  3. 确保所有OpenGL相关的操作都在有效的上下文中进行。在渲染循环中,确保在调用OpenGL函数之前,已经通过GL.createCapabilities()创建了有效的OpenGL上下文。

如果您遵循这些步骤,问题可能会得到解决。如果问题仍然存在,请提供更多关于您的应用程序结构和上下文管理的详细信息,以便我可以更准确地帮助您找出问题的原因。

英文:

I was on lwjgl, just coding my engine as I'm gonna reuse it for other projects. But as i was coding my shaders, and tested, it gave this error.

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.&lt;init&gt;(ShaderProgram.java:13)
	at bengine.shaders.StaticShader.&lt;init&gt;(StaticShader.java:10)
	at Main.jav$1.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

I need answers please do give answers, and tell if this has been a shut down topic.

Heres my code:

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(&quot;\n&quot;);
            }
        } 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 = &quot;src/bengine/shaders/vertShader.glsl&quot;;
    private static final String FRAGMENT_FILE = &quot;src/bengine/shaders/fragmentShader.glsl&quot;;

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

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

both shaders:

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

And the 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(&quot;Bengi engine failure: GLFW initialization failed, this is a internal error, can&#39;t be fixed.&quot;);
        }

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

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

        System.out.println(&quot;Window created.&quot;);

        glfwMakeContextCurrent(window);

        System.out.println(&quot;Context was made.&quot;);
    }

    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, &quot;hello world&quot;) {
            @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);
    }
}

and the window runner(deprecated later)

package bengine.window;

import org.jetbrains.annotations.NotNull;

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

I don't know why its happening, all my other packages in the renderer and others had the context. Please answer.

答案1

得分: 1

GL.createCapabilities(true); 必须在 init() 之前调用。注意在其中有一个抽象方法。它被覆盖,并且 StaticShader 对象在 init 中被构造。因此,必须先确保 OpenGL 能力:

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

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

        glfwPollEvents();
    }
}
英文:

GL.createCapabilities(true); has to be called before init(). Note in the is an abstract method. It is overridden and the StaticShader object is constructed in init. Therefore, the OpenGL capability must be ensured beforehand:

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

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

        glfwPollEvents();
    }
}

huangapple
  • 本文由 发表于 2020年9月22日 18:17:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/64007656.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定