LWJGL Forum

Please login or register.

Login with username, password and session length
Pages: [1] 2 3 ... 10
 1 
 on: Today at 08:58:02 
Started by Fataho - Last post by Fataho
Now it works perfectly and it has no lag in main thread while the model is being loaded. I have done very stupid mistake. Thank you very much for showing me the solution and for your tip to use glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE) and GLUtil.setupDebugMessageCallback().

 2 
 on: Today at 08:05:38 
Started by Fataho - Last post by spasi
The call GL30.glBindVertexArray(vaoId); in run() triggers an OpenGL error. You cannot share VAOs between OpenGL contexts. This means that indicesVboId, which is created in the secondary thread and was supposed to be part of the VAO state, is effectively never bound in the main thread, so glDrawElements crashes.

Using glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE) and GLUtil.setupDebugMessageCallback() (after the call to GL.createCapabilities()) is highly recommended when developing OpenGL programs.

 3 
 on: Today at 02:03:16 
Started by Fataho - Last post by Fataho
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:

Code: [Select]
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:
Code: [Select]
#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:
Code: [Select]
#version 400 core
in vec3 colour;
out vec4 out_Color;
void main(void){
    out_Color = vec4(colour, 1.0);
}

 4 
 on: February 26, 2017, 17:56:27 
Started by Fataho - Last post by spasi
The crash is in the Nvidia driver, which suggests a bug in your code. It would help if you could post a short program (without dependencies other than lwjgl) that reproduces the crash.

 5 
 on: February 26, 2017, 17:06:48 
Started by Fataho - Last post by Fataho
Hello,
I try load 3D object on separate thread on separate OpenGL context. To do that I create separate worker window:
Code: [Select]
glfwWindowHint(GLFW_VISIBLE, GL11.GL_FALSE);
terrainLoaderWindowID = glfwCreateWindow(1, 1, "", MemoryUtil.NULL, mainWindowID);
if (terrainLoaderWindowID == MemoryUtil.NULL)
    throw new RuntimeException("Failed to create the GLFW window");
In separate thread I make context current for that worker window:
Code: [Select]
glfwMakeContextCurrent(terrainLoaderWindowID);
GL.createCapabilities();
and load up the model. However when I call:
Code: [Select]
GL11.glDrawElements(GL11.GL_TRIANGLES, entity.getModel().getVertexCount(), GL11.GL_UNSIGNED_INT, 0);
I get EXCEPTION_ACCESS_VIOLATION (0xc0000005), log file is attached.
Everything works if I do the same thing in one context. Can any one tell me what I am doing wrong? I can easily provide more info if it is necessary. Thank you.

 6 
 on: February 26, 2017, 15:40:37 
Started by DanielUnleashed - Last post by spasi
That is not the correct way to iterate the scene materials. Also, AIMaterialProperty structs are not usually accessed by the user directly, the more convenient aiGetMaterial<property> functions are used instead. Example code:

Code: [Select]
PointerBuffer materials = scene.mMaterials(); // array of pointers to AIMaterial structs
for ( int i = 0; i < materials.remaining(); i++ ) {
AIMaterial material = AIMaterial.create(materials.get(i)); // wrap raw pointer in AIMaterial instance

// Method 1: use aiGetMaterial<property> functions, e.g.
int texCount = aiGetMaterialTextureCount(material, aiTextureType_DIFFUSE);

// Method 2: Parse material properties manually
PointerBuffer properties = material.mProperties(); // array of pointers to AIMaterialProperty structs
for ( int j = 0; j < properties.remaining(); j++ ) {
AIMaterialProperty prop = AIMaterialProperty.create(properties.get(j));
// parse property
}
}

Finally, material.close() or material.free() should not be called. The memory backing the materials is allocated by Assimp and is part of the AIScene object, it will be deallocated when you call aiReleaseImport(scene).

 7 
 on: February 26, 2017, 12:35:53 
Started by DanielUnleashed - Last post by DanielUnleashed
So, the name explains it very well:
I've been struggling with Assimp because I cannot get the properties of a material, and well, I'm searching for help or maybe a link where I can find information.
So far, this is what I got.
Code: [Select]
int numMaterials = scene.mNumMaterials();
int[] materialRemap = new int[numMaterials];
for(int i = 0; i < numMaterials; i++){
AIMaterial material = new AIMaterial(scene.mMaterials().getByteBuffer(1288));
for(int j = 0; j < material.mNumProperties(); j++){
AIMaterialProperty prop = new AIMaterialProperty(material.mProperties().getByteBuffer(1288));
                                // What now?
}
material.close();
}
Any help will be well received, thank you!

 8 
 on: February 24, 2017, 07:45:05 
Started by Gojira - Last post by spasi
glfwMakeContextCurrent() makes the "context" current, and then GL.createCapabilities() binds that context to the LWJGL and the OpenGL library?

There is no context handle stored somewhere in LWJGL. The call to GL.createCapabilities() retrieves the OpenGL function pointers that correspond to the context that is current in the current thread and also populates the capability flags (which core versions and extensions are supported). This information is stored in a GLCapabilities object, which is then stored in thread-local storage. If there are multiple contexts made current in the same thread, the GL.setCapabilities() method can be called to reuse an existing GLCapabilities instance.

When and how the context is actually made current, is managed externally. GLFW does it own context management and so do other libraries. You can do your own context creation and management in LWJGL, but you have to use OS-specific APIs (i.e. CGL, GLX, WGL, EGL).

I can call GL.createCapabilities() anytime after glfwMakeContextCurrent() and it will work?

Yes. You can call GL.createCapabilities() anytime you know there is an OpenGL context current in the current thread.

Just curious: how is this context passed since the GL.createCapabilities() method doesn't take any parameters?

LWJGL uses the OS-specific APIs mentioned above to retrieve the current context from the current thread and query its capabilities.

 9 
 on: February 23, 2017, 22:52:23 
Started by Gojira - Last post by Gojira
So let me see if I have this straight.

glfwMakeContextCurrent() makes the "context" current, and then GL.createCapabilities() binds that context to the LWJGL and the OpenGL library?  I can call GL.createCapabilities() anytime after glfwMakeContextCurrent() and it will work?

Just curious: how is this context passed since the GL.createCapabilities() method doesn't take any parameters?

 10 
 on: February 23, 2017, 22:08:55 
Started by Gojira - Last post by Kai
The documentation is correct, and so is the HelloWorld example on the Getting Started page.

Your assumption that calling GLFW functions means "calling GL functions" is not correct.

Methods on the GLFW class, such as glfwWindowHint() and glfwCreateWindow() and even glfwMakeContextCurrent() are neither OpenGL functions nor do they at any point call OpenGL functions internally.
They are used to create a window and with it an OpenGL context.
(Btw. whenever you see "GL functions" in the context of OpenGL/GLFW/LWJGL, that "GL" usually means "OpenGL")
That means, the OpenGL context is actually being created by the glfwCreateWindow() method internally. In order to use OpenGL functions for this context, that context must be made "current" in the executing thread by calling glfwMakeContextCurrent().
The OpenGL context is now both created and current in the executing thread.

In order for LWJGL to actually know about the OpenGL context and initialize itself using that context, we have to call GL.createCapabilities().
It is only after that call that we can call OpenGL functions via methods on those GLxx and extension classes living in the org.lwjgl.opengl package.

Pages: [1] 2 3 ... 10