我无法解决有问题的问题。我尝试了几个解决这个错误的方法但没有任何积极的结果。如果我尝试删除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()方法的位置,但我不知道如何解决。 说明我是初学者,现在我正在接近创建视频游戏。
提前感谢任何解决方案。