Vertex array not initialized (New Problem, OpenGL)

Started by ChessIndustries, June 07, 2018, 17:33:13

Previous topic - Next topic

ChessIndustries

For some reason when I attempt to run my code to create a triangle, the JVM crashes giving me an error. This is the code:
public void render(float delta) {

		glClear(GL_COLOR_BUFFER_BIT);

		shaderProgram.bindProgram();

		glBindVertexArray(vaoID);
		glEnableVertexAttribArray(0);

		glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0);

		glDisableVertexAttribArray(0);
		glBindVertexArray(0);

		shaderProgram.unbindProgram();
	}

	public void dispose() {

		// Dispose the program
		shaderProgram.cleanup();

		// Dispose the vertex array
		glBindVertexArray(0);
		glDeleteVertexArrays(vaoID);

		// Dispose the buffer object
		glBindBuffer(GL_ARRAY_BUFFER, 0);
		glDeleteBuffers(vboID);
	}
	
	
    public void init()
    {
 


    	shaderProgram = new ShaderClass();
        // Generate and bind a Vertex Array
        vaoID = glGenVertexArrays();
        glBindVertexArray(vaoID);
        vboID = glGenBuffers();

        // The vertices of our Triangle
        float[] vertices = new float[]
        {
            +0.0f, +0.8f,    
            -0.8f, -0.8f,    
            +0.8f, -0.8f     
        };

        // Create a FloatBuffer of vertices
        FloatBuffer verticesBuffer = BufferUtils.createFloatBuffer(vertices.length);
        verticesBuffer.put(vertices).flip();

        // Create a Buffer Object and upload the vertices buffer
        
        glBindBuffer(GL_ARRAY_BUFFER, vboID);
        glBufferData(GL_ARRAY_BUFFER, verticesBuffer, GL_STATIC_DRAW);

        // Point the buffer at location 0, the location we set
        // inside the vertex shader. You can use any location
        // but the locations should match
        glVertexAttribPointer(0, 2, GL_FLOAT, false, 0, 0);
        glBindVertexArray(0);
    }

And this is the error:

https://pastebin.com/UkPpn9W7

If anyone could find out what this error means and how to fix it, it would be greatly appreciated. For some reason this wont work on my computer, but on my friends it does. Thank you!

KaiHH

You are calling glDrawElements without having a buffer object bound to GL_ELEMENT_ARRAY_BUFFER. In this case, the last argument 0 is interpreted as the virtual memory address of a client-provided element array. And since no process can dereference from address 0, the process crashes. Only when you have a buffer object bound to said binding point will the last argument be interpreted as a byte offset into that buffer.

You probably wanted to use glDrawArrays.

ChessIndustries

Thanks for the fast reply! However, even if I change it to glDrawArrays() it still has a JVM Error and crashes.

KaiHH

Can you show your updated code?

ChessIndustries

public void render(float delta) {

		glClear(GL_COLOR_BUFFER_BIT);

		shaderProgram.bindProgram();

		glBindVertexArray(vaoID);
		glEnableVertexAttribArray(0);

		glDrawArrays(GL_TRIANGLES, 0, 3);

		glDisableVertexAttribArray(0);
		glBindVertexArray(0);

		shaderProgram.unbindProgram();
	}

	public void dispose() {

		// Dispose the program
		shaderProgram.cleanup();

		// Dispose the vertex array
		glBindVertexArray(0);
		glDeleteVertexArrays(vaoID);

		// Dispose the buffer object
		glBindBuffer(GL_ARRAY_BUFFER, 0);
		glDeleteBuffers(vboID);
	}
	
	
    public void init()
    {
 


    	shaderProgram = new ShaderClass();
        // Generate and bind a Vertex Array
        vaoID = glGenVertexArrays();
        glBindVertexArray(vaoID);
        vboID = glGenBuffers();

        // The vertices of our Triangle
        float[] vertices = new float[]
        {
            +0.0f, +0.8f,    
            -0.8f, -0.8f,    
            +0.8f, -0.8f     
        };

        // Create a FloatBuffer of vertices
        FloatBuffer verticesBuffer = BufferUtils.createFloatBuffer(vertices.length);
        verticesBuffer.put(vertices).flip();

        // Create a Buffer Object and upload the vertices buffer
        
        glBindBuffer(GL_ARRAY_BUFFER, vboID);
        glBufferData(GL_ARRAY_BUFFER, verticesBuffer, GL_STATIC_DRAW);

        // Point the buffer at location 0, the location we set
        // inside the vertex shader. You can use any location
        // but the locations should match
        glVertexAttribPointer(0, 2, GL_FLOAT, false, 0, 0);
        glBindVertexArray(0);
    }

KaiHH

Are you absolutely 100% sure that init() is called before the first render() call? Debug the render() method and check the value of the vaoID field.

ChessIndustries

I checked, and the init() happens before and calls both the vaoID being created and the vboID. In the main method the engine is called to start and does init() and then gameloop(), with the init method being in the init and the render method being in the gameloop(). Sometimes instead of a jvm error it immediately goes into not responding mode.

KaiHH

Try excecuting your Java program with the https://github.com/LWJGLX/debug Java agent. It can be downloaded from https://www.lwjgl.org/customize . Select "LWJGLX/debug v1.0.0" under "Addons", place the jar in a folder <folder> and execute your program with the JVM argument -javaagent:<folder>/lwjglx-debug-1.0.0.jar.
And post the console output.

ChessIndustries

[LWJGL] Version: 3.1.6 build 14
[LWJGL] 	 OS: Windows 7 v6.1
[LWJGL] 	JRE: 10.0.1 amd64
[LWJGL] 	JVM: Java HotSpot(TM) 64-Bit Server VM v10.0.1+10 by "Oracle Corporation"
[LWJGL] Loading library (system): lwjgl
[LWJGL] 	Using SharedLibraryLoader...
[LWJGL] 	Found at: C:\Users\johnson\AppData\Local\Temp\lwjgljohnson\3.1.6-build-14\lwjgl.dll
[LWJGL] 	Loaded from org.lwjgl.librarypath: C:\Users\johnson\AppData\Local\Temp\lwjgljohnson\3.1.6-build-14\lwjgl.dll
[LWJGL] Loading library (system): lwjgl_opengl
[LWJGL] 	Using SharedLibraryLoader...
[LWJGL] 	Found at: C:\Users\johnson\AppData\Local\Temp\lwjgljohnson\3.1.6-build-14\lwjgl_opengl.dll
[LWJGL] 	Loaded from org.lwjgl.librarypath: C:\Users\johnson\AppData\Local\Temp\lwjgljohnson\3.1.6-build-14\lwjgl_opengl.dll
[LWJGL] Loading library: opengl32
[LWJGL] 	opengl32.dll not found in org.lwjgl.librarypath=C:\Users\johnson\AppData\Local\Temp\lwjgljohnson\3.1.6-build-14
[LWJGL] MemoryUtil accessor: MemoryAccessorUnsafe
[LWJGL] 	Loaded from system paths
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.checkCapabilities(GL.java:256)
	at org.lwjgl.opengl.GL.getCapabilities(GL.java:251)
	at org.lwjglx.debug.$Proxy$11.37(Unknown Source)
	at Shaders.ShaderClass.<init>(ShaderClass.java:14)
	at Rendering.Renderer.init(Renderer.java:74)
	at Engine.Engine.init(Engine.java:71)
	at Engine.Engine.run(Engine.java:59)
	at java.base/java.lang.Thread.run(Unknown Source)

KaiHH

This actually means that you are calling OpenGL functions before you initialize the OpenGL context properly in LWJGL3 or maybe even before you create the window/OpenGL context. Debug your program thoroughly step-by-step to see what is done when and in which order.

KaiHH

Also please change the JVM argument to: -javaagent:<folder>/lwjglx-debug-1.0.0.jar=t
(append an equal sign followed by a lower case T).
And post the output here. This will produce a trace log of all LWJGL calls you are doing.
This will show when you are calling which methods.

ChessIndustries

[LWJGL] Version: 3.1.6 build 14
[LWJGL]     OS: Windows 7 v6.1
[LWJGL]    JRE: 10.0.1 amd64
[LWJGL]    JVM: Java HotSpot(TM) 64-Bit Server VM v10.0.1+10 by "Oracle Corporation"
[LWJGL] Loading library (system): lwjgl
[LWJGL]    Using SharedLibraryLoader...
[LWJGL]    Found at: C:\Users\johnson\AppData\Local\Temp\lwjgljohnson\3.1.6-build-14\lwjgl.dll
[LWJGL]    Loaded from org.lwjgl.librarypath: C:\Users\johnson\AppData\Local\Temp\lwjgljohnson\3.1.6-build-14\lwjgl.dll
[LWJGL] MemoryUtil accessor: MemoryAccessorUnsafe
[LWJGL] MemoryUtil allocator: DebugAllocator
[LWJGL] Loading library: glfw
[LWJGL]    Using SharedLibraryLoader...
[LWJGL]    Found at: C:\Users\johnson\AppData\Local\Temp\lwjgljohnson\3.1.6-build-14\glfw.dll
[LWJGL]    Loaded from org.lwjgl.librarypath: C:\Users\johnson\AppData\Local\Temp\lwjgljohnson\3.1.6-build-14\glfw.dll
[trace] (Window.java:37)       createPrint(java.io.PrintStream@2ad64aa6) =  pointer [0x3F0000]
java.lang.IllegalStateException: Method glfwInit was called in thread [Thread[GAME_LOOP_THREAD,5,main]] which is not the main thread.
   at Rendering.Window.init(Window.java:40)
   at Engine.Engine.init(Engine.java:71)
   at Engine.Engine.run(Engine.java:59)
   at java.base/java.lang.Thread.run(Unknown Source)
[LWJGL] 16 bytes leaked, thread 13 (GAME_LOOP_THREAD), address: 0x3F0000
   at org.lwjgl.system.Callback.create(Callback.java:133)
   at org.lwjgl.system.Callback.<init>(Callback.java:83)
   at org.lwjgl.glfw.GLFWErrorCallback.<init>(GLFWErrorCallback.java:60)
   at org.lwjgl.glfw.GLFWErrorCallback$1.<init>(GLFWErrorCallback.java:97)
   at org.lwjgl.glfw.GLFWErrorCallback.createPrint(GLFWErrorCallback.java:97)
   at org.lwjglx.debug.$Proxy$6.17(Unknown Source)
   at Rendering.Window.init(Window.java:37)
   at Engine.Engine.init(Engine.java:71)
   at Engine.Engine.run(Engine.java:59)
   at java.base/java.lang.Thread.run(Unknown Source)

KaiHH

Okay.... you actually have multiple issues in your code. The next one now is that you are initializing GLFW (and probably also creating your window) inside another thread other than the Thread executing the public static void main(String[] args) method. This is not supported on all platforms and therefore LWJGLX/debug complains about it. Please read the documentation of GLFW to see which methods are safe to call in any thread.
Now, to see more errors you can change the JVM argument to: -javaagent:...=tn (append an additional lowercase N).

ChessIndustries

That's weird because I only have one thread so far. Anyways, here is it with the appended n. It's quite big, so I attached it to a pastebin:
https://pastebin.com/H0BDATrT

KaiHH

Quote from: ChessIndustries on June 07, 2018, 19:27:18
That's weird because I only have one thread so far.
You have two threads. One that is created implicitly by the operating system to execute your Java process (like I said, this is the thread which calls the initial public static void main(String[] args) method) and you create a second thread manually which will execute your Engine code and initialize GLFW, which as I said you cannot/mustnot do.