Reputation: 21
I've been trying OpenGL, following ThinMatrix's tutorials. Only thing I'm doing differently is he was using lwjgl 2 and i'm using 3. I thought it would be a good challenge, and it has definitely proven to be. It say's no glcapabilities have been set but I'm pretty sure I set them already!
Basically the full error I'm getting is
Exception in thread "main" java.lang.IllegalStateException: No GLCapabilities instance has been set for the current thread.
at org.lwjgl.opengl.GL.getCapabilities(GL.java:211)
at org.lwjgl.opengl.GL20.getInstance(GL20.java:378)
at org.lwjgl.opengl.GL20.glCreateShader(GL20.java:464)
at net.robharding.base.shaders.ShaderProgram.loadShader(ShaderProgram.java:67)
at net.robharding.base.shaders.ShaderProgram.<init>(ShaderProgram.java:17)
at net.robharding.base.shaders.StaticShader.<init>(StaticShader.java:9)
at net.robharding.base.engine.Display.init(Display.java:77)
at net.robharding.base.engine.Display.<init>(Display.java:31)
at net.robharding.base.MainComponent.main(MainComponent.java:8)
To me, this makes no sense because I Did do GL.CreateCapabilities();, and I can't find anything online about this error...
package net.robharding.base.engine;
import org.lwjgl.glfw.*;
import org.lwjgl.opengl.*;
import net.robharding.base.shaders.StaticShader;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.system.MemoryUtil.*;
public class Display {
private String title;
private int width, height;
@SuppressWarnings("unused")
private GLFWErrorCallback errorCallback;
@SuppressWarnings("unused")
private GLFWKeyCallback keyCallback;
private long windowID;
private Loader loader;
private Renderer renderer;
private StaticShader shader;
public Display(String title, int width, int height) {
this.title = title;
this.width = width;
this.height = height;
init();
}
private void keyPressed(int key, int scancode, int mods) {
}
private void keyReleased(int key, int scancode, int mods) {
if(key == GLFW_KEY_ESCAPE)
glfwSetWindowShouldClose(windowID, GLFW_TRUE);
}
private void init() {
// Setup an error callback. The default implementation
// will print the error message in System.err.
glfwSetErrorCallback(errorCallback = GLFWErrorCallback.createPrint(System.err));
if(glfwInit() != GLFW_TRUE)
throw new IllegalStateException("Unable to initialize GLFW");
glfwDefaultWindowHints();
glfwWindowHint(GLFW_VISIBLE, GLFW_TRUE);
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
windowID = glfwCreateWindow(width, height, title, NULL, NULL);
if(windowID == NULL)
throw new RuntimeException("Failed to create the GLFW window");
glfwSetKeyCallback(windowID, keyCallback = new GLFWKeyCallback() {
@Override
public void invoke(long window, int key, int scancode, int action, int mods) {
if(action == GLFW_PRESS)
keyPressed(key, scancode, mods);
else if(action == GLFW_RELEASE)
keyReleased(key, scancode, mods);
}
});
GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
glfwSetWindowPos(windowID, (vidmode.width() - width) / 2, (vidmode.height() - height) / 2);
glfwMakeContextCurrent(windowID);
glfwSwapInterval(1);
loader = new Loader();
renderer = new Renderer();
shader = new StaticShader();
glfwShowWindow(windowID);
}
public void run() {
GL.createCapabilities();
GL11.glViewport(0, 0, width, height);
float[] vertices = {
-0.5f, 0.5f, 0, // V1
-0.5f, -0.5f, 0, // V2
0.5f, -0.5f, 0, // V3
0.5f, 0.5f, 0 // V4
};
int[] indices = {
0, 1, 3,
3, 2, 1
};
RawModel model = loader.loadToVAO(vertices, indices);
while(glfwWindowShouldClose(windowID) == GLFW_FALSE) {
renderer.prepare();
shader.start();
renderer.render(model);
shader.stop();
glfwSwapBuffers(windowID);
glfwPollEvents();
}
shader.cleanUp();
loader.cleanUp();
}
}
Here is the method where it's tracing back to.
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");
}
reader.close();
} catch(IOException e) {
System.err.print("Count not read file!");
e.printStackTrace();
System.exit(-1);
}
int shaderID = GL20.glCreateShader(type);
GL20.glShaderSource(shaderID, shaderSource);
GL20.glCompileShader(shaderID);
if(GL20.glGetShaderi(shaderID, GL20.GL_COMPILE_STATUS) == GL11.GL_FALSE) {
System.out.println(GL20.glGetShaderInfoLog(shaderID, 500));
System.err.println("Could not compile shader!");
System.exit(-1);
}
return shaderID;
}
Upvotes: 2
Views: 2024
Reputation: 22174
Your code tries to use OpenGL before you have created the context.
The init
method in which the shader is created is called in the constructor, but the context is created in the begin of the run
method. To solve this, move the call of the init
method to the run
method after GL.createCapabilities();
.
Please also note, that OpenGL contexts are always associated with exactly one thread. So all OpenGL commands have to be issued from this one thread.
Upvotes: 3