Thank you for your replay. I tried to do what you ask. Everything works fine if I use one window, however when I use two windows, I get that VIOLATION, log file is attached. Please, let me know if you need more things from me. Here is the code:
import org.lwjgl.BufferUtils;
import org.lwjgl.glfw.GLFWErrorCallback;
import org.lwjgl.opengl.*;
import org.lwjgl.system.MemoryUtil;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import static org.lwjgl.glfw.Callbacks.glfwFreeCallbacks;
import static org.lwjgl.glfw.GLFW.*;
public class FTH extends Thread{
private long mainWindowID;
private long secondWindowID;
float[] vertices = {
-0.5f,0.5f,-0.5f,-0.5f,-0.5f,-0.5f,0.5f,-0.5f,-0.5f,0.5f,0.5f,-0.5f,
-0.5f,0.5f,0.5f,-0.5f,-0.5f,0.5f,0.5f,-0.5f,0.5f,0.5f,0.5f,0.5f,
0.5f,0.5f,-0.5f,0.5f,-0.5f,-0.5f,0.5f,-0.5f,0.5f, 0.5f,0.5f,0.5f,
-0.5f,0.5f,-0.5f,-0.5f,-0.5f,-0.5f,-0.5f,-0.5f,0.5f,-0.5f,0.5f,0.5f,
-0.5f,0.5f,0.5f,-0.5f,0.5f,-0.5f,0.5f,0.5f,-0.5f,0.5f,0.5f,0.5f,
-0.5f,-0.5f,0.5f,-0.5f,-0.5f,-0.5f,0.5f,-0.5f,-0.5f,0.5f,-0.5f,0.5f
};
int[] indices = {
0,1,3,3,1,2,4,5,7,7,5,6,8,9,11,11, 9,10,12,13,15,
15,13,14,16,17,19,19,17, 18,20,21,23,23,21,22
};
private int vaoId;
private int verticesVBOId;
private int indicesVboId;
private boolean modelLoadedToVRAM = false;
int vertexShaderID;
int fragmentShaderID;
int programID;
public static void main(String[] args) {
FTH fth = new FTH();
fth.initialize();
fth.loop();
fth.cleanUp();
}
private void initialize(){
GLFWErrorCallback.createPrint(System.err).set();
if ( !glfwInit() )
throw new IllegalStateException("Unable to initialize GLFW");
glfwDefaultWindowHints(); // optional, the current window hints are already the default
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); // the window will stay hidden after creation
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); // the window will be resizable
glfwWindowHint(GLFW_SAMPLES, 16); // For antialiasing
// Create the main window
mainWindowID = glfwCreateWindow(1024, 576, "Main Window", MemoryUtil.NULL, MemoryUtil.NULL);
if (mainWindowID == MemoryUtil.NULL)
throw new RuntimeException("Failed to create the GLFW window");
glfwMakeContextCurrent(mainWindowID);
// Second window
glfwWindowHint(GLFW_VISIBLE, GL11.GL_FALSE);
secondWindowID = glfwCreateWindow(1, 1, "", MemoryUtil.NULL, mainWindowID);
if (secondWindowID == MemoryUtil.NULL)
throw new RuntimeException("Failed to create the GLFW window");
glfwSwapInterval(1);
glfwShowWindow(mainWindowID);
GL.createCapabilities();
// Initialize shaders
vertexShaderID = loadShader("src/vertexShader.txt", GL20.GL_VERTEX_SHADER);
fragmentShaderID = loadShader("src/fragmentShader.txt", GL20.GL_FRAGMENT_SHADER);
programID = GL20.glCreateProgram();
GL20.glAttachShader(programID, vertexShaderID);
GL20.glAttachShader(programID, fragmentShaderID);
GL20.glBindAttribLocation(programID, 0, "position");
GL20.glLinkProgram(programID);
GL20.glValidateProgram(programID);
// CREATE EMPTY VABO IN MAIN THREAD
vaoId = GL30.glGenVertexArrays();
GL30.glBindVertexArray(vaoId);
verticesVBOId = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, verticesVBOId);
FloatBuffer vertices = BufferUtils.createFloatBuffer(0);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, vertices, GL15.GL_STATIC_DRAW);
GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 0, 0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GL30.glBindVertexArray(0);
// When empty VABO is created, start the thread that loads the model, see run() method below
start();
}
// THE LOOP
private void loop(){
while(!glfwWindowShouldClose(mainWindowID)) {
if(isModelLoadedToVRAM()){
GL11.glEnable(GL11.GL_DEPTH_TEST);
GL11.glClearColor(0.1f, 0.3f, 0.5f, 0.0f);
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
GL20.glUseProgram(programID);
GL30.glBindVertexArray(vaoId);
GL20.glEnableVertexAttribArray(0);
GL11.glDrawElements(GL11.GL_TRIANGLES, indices.length, GL11.GL_UNSIGNED_INT, 0);
GL20.glDisableVertexAttribArray(0);
GL30.glBindVertexArray(0);
GL20.glUseProgram(0);
}
glfwSwapBuffers(mainWindowID);
glfwPollEvents();
}
}
private void cleanUp(){
GL30.glDeleteVertexArrays(vaoId);
GL15.glDeleteBuffers(verticesVBOId);
GL15.glDeleteBuffers(indicesVboId);
GL20.glUseProgram(0);
GL20.glDetachShader(programID, vertexShaderID);
GL20.glDetachShader(programID, fragmentShaderID);
GL20.glDeleteShader(vertexShaderID);
GL20.glDeleteShader(fragmentShaderID);
GL20.glDeleteProgram(programID);
// Free the window callbacks and destroy the window
glfwFreeCallbacks(mainWindowID); // Release the key callback
glfwDestroyWindow(mainWindowID);
glfwDestroyWindow(secondWindowID);
// Terminate GLFW and free the error callback
glfwTerminate();
glfwSetErrorCallback(null).free();
}
// THREAD CODE
public void run(){
glfwMakeContextCurrent(secondWindowID);
GL.createCapabilities();
GL30.glBindVertexArray(vaoId);
// Store data into VBO
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, verticesVBOId);
FloatBuffer verticesBuffer = BufferUtils.createFloatBuffer(vertices.length);
verticesBuffer.put(vertices);
verticesBuffer.flip();
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, verticesBuffer, GL15.GL_STATIC_DRAW);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
// Bind indices
indicesVboId = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, indicesVboId);
IntBuffer indicesBuffer = BufferUtils.createIntBuffer(indices.length);
indicesBuffer.put(indices);
indicesBuffer.flip(); //
GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indicesBuffer, GL15.GL_STATIC_DRAW);
GL30.glBindVertexArray(0);
glfwMakeContextCurrent(MemoryUtil.NULL);
// Inform that model is loaded
setModelLoadedToVRAM(true);
}
public 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.println("Could 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.out.println("Could not compile shader!");
System.exit(-1);
}
return shaderID;
}
public synchronized boolean isModelLoadedToVRAM() {
return modelLoadedToVRAM;
}
public synchronized void setModelLoadedToVRAM(boolean modelLoadedToVRAM) {
this.modelLoadedToVRAM = modelLoadedToVRAM;
}
}
Vertex Shader code:
#version 400 core
in vec3 position;
out vec3 colour;
void main (void){
gl_Position = vec4(position, 1.0);
colour = vec3(position.x + 0.5, 1.0, position.y + 0.5);
}
Fragment Shader code:
#version 400 core
in vec3 colour;
out vec4 out_Color;
void main(void){
out_Color = vec4(colour, 1.0);
}