英文:
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上下文的管理有关。请确保以下几点:
-
确保在同一线程上管理OpenGL上下文。在您的代码中,看起来您在
CustomWindow
的gameloop
方法中调用了glfwInit()
,这可能会导致问题。通常情况下,应在主线程中初始化GLFW一次,然后在渲染循环中管理OpenGL上下文。 -
确保OpenGL的初始化和上下文管理在正确的顺序中进行。在
CustomWindow
的构造函数中,您应该首先调用glfwInit()
,然后创建窗口,然后在gameloop
方法中初始化OpenGL上下文。 -
确保所有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.<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)
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("\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");
}
}
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("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);
}
}
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();
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论