How to clear the context on the thread? What command should be used? I try to load info into VBO on separate thread and I am getting similar error. What I am doing wrong?
[LWJGL] GLFW_PLATFORM_ERROR error
Description : WGL: Failed to make context current: The requested resource is in use.
Stacktrace :
org.lwjgl.glfw.GLFW.glfwMakeContextCurrent(GLFW.java:3397)
fataho.engine.Loader.lambda$loadTexturedModelWithSeparateThread$0(Loader.java:68)
java.lang.Thread.run(Thread.java:745)
Exception in thread "Thread-0" java.lang.IllegalStateException: There is no OpenGL context current in the current thread.
at org.lwjgl.opengl.GL.createCapabilities(GL.java:351)
at org.lwjgl.opengl.GL.createCapabilities(GL.java:302)
at fataho.engine.Loader.lambda$loadTexturedModelWithSeparateThread$0(Loader.java:69)
at java.lang.Thread.run(Thread.java:745)
My code:
private int verticesVBOId;
private int texturesVBOId;
private int normalsVBOId;
private int textureId;
public TexturedModel loadTexturedModelWithSeparateThread(float[] verticesArray
, float[] textureArray
, float[] normalsArray
, int[] indicesArray
, String textureFilePathAndName){
int vaoId = createVAO();
bindVAO(vaoId);
new Thread(() -> {
glfwMakeContextCurrent(Window.windowID);
GL.createCapabilities();
verticesVBOId = createVBO(verticesArray);
texturesVBOId = createVBO(textureArray);
normalsVBOId = createVBO(normalsArray);
bindIndices(indicesArray);
textureId = loadTexture(textureFilePathAndName);
}).start();
storeDataInAttributeList(verticesVBOId, 0, 3);
storeDataInAttributeList(texturesVBOId, 1, 2);
storeDataInAttributeList(normalsVBOId, 2, 3);
unBindVAO();
return new TexturedModel(vaoId, indicesArray.length, textureId);
}
private int createVAO(){
int vaoId = GL30.glGenVertexArrays();
vaoIds.add(vaoId);
return vaoId;
}
private void bindVAO(int vaoId){
GL30.glBindVertexArray(vaoId);
}
private void unBindVAO(){
GL30.glBindVertexArray(0);
}
private synchronized int createVBO(float[] data){
int vboId = GL15.glGenBuffers();
vaoIds.add(vboId);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboId);
FloatBuffer verticesBuffer = storeDataInFloatBuffer(data);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, verticesBuffer, GL15.GL_STATIC_DRAW);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
return vboId;
}
private synchronized void storeDataInAttributeList(int vboId, int attributeNumber, int coordinateSize){
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboId);
GL20.glVertexAttribPointer(attributeNumber, coordinateSize, GL11.GL_FLOAT, false, 0, 0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
}
private int loadTexture(String modelFileLocationAndName){
int bytesPerPixel = 4; // 3 for RGB, 4 for RGBA
BufferedImage image = null;
try {
image = ImageIO.read(new File(modelFileLocationAndName));
} catch (IOException e) {
//Error Handling Here
e.printStackTrace();
}int[] pixels = new int[image.getWidth() * image.getHeight()];
image.getRGB(0, 0, image.getWidth(), image.getHeight(), pixels, 0, image.getWidth());
ByteBuffer buffer = BufferUtils.createByteBuffer(image.getWidth() * image.getHeight() * bytesPerPixel); // 4 for RGBA, 3 for RGB
for(int y = 0; y < image.getHeight(); y++){
for(int x = 0; x < image.getWidth(); x++){
int pixel = pixels[y * image.getWidth() + x];
buffer.put((byte) ((pixel >> 16) & 0xFF)); // Red component
buffer.put((byte) ((pixel >> 8) & 0xFF)); // Green component
buffer.put((byte) (pixel & 0xFF)); // Blue component
buffer.put((byte) ((pixel >> 24) & 0xFF)); // Alpha component. Only for RGBA
}
}
buffer.flip(); //FOR THE LOVE OF GOD DO NOT FORGET THIS
// You now have a ByteBuffer filled with the color data of each pixel.
// Now just create a texture ID and bind it. Then you can load it using
// whatever OpenGL method you want, for example:
int textureID = glGenTextures(); //Generate texture ID
glBindTexture(GL_TEXTURE_2D, textureID); //Bind texture ID
//Setup wrap mode
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE);
//Setup textureBuffer scaling filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
//Send texel data to OpenGL
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, image.getWidth(), image.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
// Mip mapping
// GL30.glGenerateMipmap(GL11.GL_TEXTURE_2D);
// GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR_MIPMAP_LINEAR);
// GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL14.GL_TEXTURE_LOD_BIAS, -1); // enter -1 if using Anisotropic filtering, ese -0,4f
// Anisotropic filtering, not sure for 100 %, I can't check compatibility context
float amount = Math.min(4f, GL11.glGetFloat(EXTTextureFilterAnisotropic.GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT));
GL11.glTexParameterf(GL11.GL_TEXTURE_2D, EXTTextureFilterAnisotropic.GL_TEXTURE_MAX_ANISOTROPY_EXT, amount);
return textureID;
}