[LWJGL3/OpenGL] New window mode versus VAO

I’m making use of a VBO inside of a VAO to keep track of many updating verts. I’m working on the ability to change window modes. These windows are through GLFW as it is with LWJGL3.

If I’m changing window modes, as I understand it, I need to destroy the window to go from fullscreen => window => window borderless. When I do this, my VAO seems to get damanged.

I get this error after destroying window:

Message: GL_INVALID_OPERATION error generated. VAO names must be generated with glGenVertexArrays before they can be bound or used.

I don’t believe I run an action that should harm the VAO here, but sure enough it is pist.

I will provide how I’m setting up my VAO (and VBO) if nothing else than as a point of reference if you can help. I’ve researched, but I’m struggling with the proper terms or concepts to find the right information.

VBO Setup:

public void setupVBO()
    {
    	/* Get width and height of framebuffer */
        long window = GLFW.glfwGetCurrentContext();
        IntBuffer widthBuffer = BufferUtils.createIntBuffer(1);
        IntBuffer heightBuffer = BufferUtils.createIntBuffer(1);
        GLFW.glfwGetFramebufferSize(window, widthBuffer, heightBuffer);
        int width = widthBuffer.get();
        int height = heightBuffer.get();
        
        /* Generate Vertex Array Object */
        vao2 = new VertexArrayObject();
        vao2.bind();

        elements = BufferUtils.createIntBuffer((2*adjacentNodesNum) * 3); //2 * 3
        
    	for(int i = 0; i < adjacentNodesNum; i++)
        {            
    		
            elements.put((i*4) + 0).put((i*4) + 1).put((i*4) + 2);
            elements.put((i*4) + 2).put((i*4) + 3).put((i*4) + 0);
        }  
    	
        //vertices.flip();
    	myFloatBuffer.flip();
        elements.flip();

        /* Generate Vertex Buffer Object */
        vbo2 = new VertexBufferObject();
        vbo2.bind(GL_ARRAY_BUFFER);        
        vbo2.uploadData(GL_ARRAY_BUFFER, myFloatBuffer, GL_DYNAMIC_DRAW);

        /* Generate Element Buffer Object */
        ebo2 = new VertexBufferObject();
        ebo2.bind(GL_ELEMENT_ARRAY_BUFFER);
        ebo2.uploadData(GL_ELEMENT_ARRAY_BUFFER, elements, GL_DYNAMIC_DRAW);

        /* Load shaders */
        vertexShader2 = Shader.loadShader(GL20.GL_VERTEX_SHADER, "resources/shadProg.vert");
        fragmentShader2 = Shader.loadShader(GL20.GL_FRAGMENT_SHADER, "resources/shadProg.frag");

        /* Create shader program */
        program2 = new ShaderProgramSr();
        program2.attachShader(vertexShader2);
        program2.attachShader(fragmentShader2);
        program2.bindFragmentDataLocation(0, "fragColor");
        program2.link();
        program2.use();

        specifyVertexAttributes();

        /* Set texture uniform */
        int uniTex = program2.getUniformLocation("texImage");
        program2.setUniform(uniTex, 0);

        /* Set model matrix to identity matrix */
        Matrix4f model = new Matrix4f();
        int uniModel = program2.getUniformLocation("model");
        program2.setUniform(uniModel, model);

        /* Set view matrix to identity matrix */
        Matrix4f view = new Matrix4f();
        int uniView = program2.getUniformLocation("view");
        program2.setUniform(uniView, view);

        /* Set projection matrix to an orthographic projection */
       Matrix4f projection = Matrix4f.orthographic(0f, width, height, 0f, -1f, 1f);
        int uniProjection = program2.getUniformLocation("projection");
        program2.setUniform(uniProjection, projection);
        
        vao2.unbind();
        vbo2.unbind(GL_ARRAY_BUFFER);
        ebo2.unbind(GL_ELEMENT_ARRAY_BUFFER);

        glUseProgram(0);
        
    }

Thank you! ;D

When you destroy the GLFW window the OpenGL context is destroyed with it. Therefore all OpenGL objects you created until then (VBOs, VAOs, FBOs, everything) get destroyed as well, and the integer handles which you kept around in Java are not valid anymore.
You can either reinitialize all OpenGL objects after creating the new window, or use GLFW’s glfwSetWindowMonitor(), which is available since the release of LWJGL 3.0.0 (on June 3rd 2016). That GLFW function itself came with GLFW 3.2.
It allows to toggle between windowed and fullscreen mode without losing the OpenGL context.

I’m assuming you’re doing this with shared contexts, basically trying to pass on the old objects to the new context before destroying the old one. Sadly, not all OpenGL objects are shared. Anything that by itself doesn’t contain any actual data is not shared between contexts. In other words, things like textures and buffers are shared because they contain data, but FBOs and VAOs are not because they only contain references to other objects.

There are lots of functions in GLFW to change the setup of the window without recreating it. You can go fullscreen, disable the decoration to make a window borderless, etc. See glfwSetWindowMonitor() and glfwSetWindowAttrib().

Thanks for the helpful responses!

I’m using glfwSetWindowMonitor() to switch between fullscreen and windowed, but glfwSetWindowAttrib() doesn’t show up like it’s not of the GLFW library. The documentation says it was added in version 3.3, but they are only on 3.2.1?

If I can change window attributes, my solution will be complete. Is there something I need to do to be able to use glfwSetWindowAttrib() or is there another method to allow me to alter the window attributes I need to alter? Decorated and resizable?

The latest nightly build of LWJGL should include the 3.3 beta version of GLFW. I use it right now. =P

That was my feeling. TYSM, theagentd! ;D

I was going to ask this on the LWJGL forum, but I’ll ask here in case you or anyone can help, theagentd.

My libraries were from LWJGL 3.1, several months ago. When I switch my libraries to the newest stuff from LWJGL, I get some errors in my build. STB has switched at least one thing:
[icode]stbtt_PackBegin(pc, bitmap, BITMAP_W, BITMAP_H, 0, 1, null);[/icode]
That now wants a long where it wanted a null.

I also have errors from GLFW. It seems to be related to this window creation stuff. This happens in the window creation method I have.
[icode]Exception in thread “main” java.lang.UnsatisfiedLinkError: Failed to locate library: lwjgl_opengl.dll[/icode]

And then many other things fail similarly because of missing that dll. They appear in eclipse as if the code is still in the support library and recognized, but many of the methods for GLFW fail. They may give a “method not found” error instead tho.

This is still true noob question, I really just don’t know what is going on. I don’t know how to best stay abreast of what may be changing in these support libraries such that I can understand what is happening here when I replace them with new stuff. Don’t think I’m missing a library, had 7 before, have 7 now, all the same names.

Do you know if this is a situation where they have heavily changed the window creation, or is that error I’m getting possibly from something else?

This was a bugfix. Pass NULL (0L) instead of null.

Starting with LWJGL 3.1.1, the OpenGL and OpenGL ES bindings require a JNI shared library to work. You need to include lwjgl-opengl-natives-.jar in your project.

[quote=“Optimo,post:7,topic:58238”]
The simplest solution is to always use the LWJGL build configurator when updating to a new version.

Thanks again, Spasi!

[quote]The simplest solution is to always use the LWJGL build configurator when updating to a new version.
[/quote]
What I meant was knowing where to find, read, and learn the information you told me about changes. Is that in the build configurator?

Should I just be using all the files given to me in those configurator zips? I got 21 jars from my standard set in the configurator, but I only used 7 before. I didn’t seem to need them all, but perhaps I’m wrong?

[quote=“Optimo,post:9,topic:58238”]
Any changes that affect users are mentioned in the release notes. See the 3.1.1 notes for this particular issue.

[quote=“Optimo,post:9,topic:58238”]
After you select the bindings you need and download the bundle, you’re supposed to use all classes jars and natives jars for the platform you’re running on. It’s very unlikely that you’re going to need all bindings. The configurator remembers your previous selection for a given browser, or you can use the Save/Load functionality when moving between browsers/computers.