glVertexAttribPointer and BindBuffer

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

glVertexAttribPointer and BindBuffer

DearDaniel
I am doing some practise on OpenGL 3. I read the hello triangle and wrote a program to generate 1000 spinning cubes. It works well. I am now revising my codes, and comparing to the codes of others. I am reading the sample code from https://github.com/elect86/helloTriangle/tree/master/HelloTriangle/src/gl3/helloTriangle. I found some difference in the codes but I have no idea why both of them works the same.

// This is my code, originally from the hello triangle code, I changed it a bit
static void bindBuffer(GL3 gl, int bufferId, float[] dataArray, int dataLoc){
        Buffer tmp = Buffers.newDirectFloatBuffer(dataArray);
        gl.glBindBuffer(GL.GL_ARRAY_BUFFER, bufferId);
        gl.glBufferData(GL.GL_ARRAY_BUFFER, dataArray.length * Float.BYTES, tmp, GL.GL_STATIC_DRAW);
        gl.glEnableVertexAttribArray(dataLoc);
        gl.glVertexAttribPointer(dataLoc, 4, GL.GL_FLOAT, false, 0, 0);
        BufferUtils.destroyDirectBuffer(tmp);
}

//This is from the small wiki page
 private void initVertexArray(GL3 gl3) {

        gl3.glGenVertexArrays(1, vertexArrayName);
        gl3.glBindVertexArray(vertexArrayName.get(0));
        {

            gl3.glBindBuffer(GL_ARRAY_BUFFER, bufferName.get(Buffer.VERTEX));
            {
                int stride = (2 + 3) * Float.BYTES;
                int offset = 0 * Float.BYTES;

                gl3.glEnableVertexAttribArray(Semantic.Attr.POSITION);
                gl3.glVertexAttribPointer(Semantic.Attr.POSITION, 2, GL_FLOAT, false, stride, offset);

                offset = 2 * Float.BYTES;
                gl3.glEnableVertexAttribArray(Semantic.Attr.COLOR);
                gl3.glVertexAttribPointer(Semantic.Attr.COLOR, 3, GL_FLOAT, false, stride, offset);
            }
            gl3.glBindBuffer(GL_ARRAY_BUFFER, 0);

            gl3.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferName.get(Buffer.ELEMENT));
        }
        gl3.glBindVertexArray(0);

        checkError(gl3, "initVao");
    }


Can anyone explain to me the following differences?

1. For the glVertexAttribPointer, the stride of my code is 0, and the sample one is none-zero. I changed my code and it's worked fine also. So, What's the stride for? Why 0 is also acceptable?

2. The sample code has a line for unbinding the Array. Which is, "gl3.glBindBuffer(GL_ARRAY_BUFFER, 0);" and "gl3.glBindVertexArray(0);"  When I add it to my code, error occurs but it didn't mentioned anything about the error. Could any tell me why I can't do this in my code? Also, as a follow up question, what is the difference between unbinding and without unbinding?

Daniel
Never Stop ... Learn more ... Be humble ...
Reply | Threaded
Open this post in threaded view
|

Re: glVertexAttribPointer and BindBuffer

gouessej
Administrator
Hi

glVertexAttribPointer with zero as a stride indicates that the generic vertex attributes are tightly packed in the array, it's acceptable:
https://www.opengl.org/sdk/docs/man/html/glVertexAttribPointer.xhtml

gl3.glBindBuffer(GL_ARRAY_BUFFER, 0) unbinds the VBO whereas gl3.glBindVertexArray(0) unbinds the VAO.

What do you mean by "error occurs but it didn't mentioned anything about the error"?
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: glVertexAttribPointer and BindBuffer

elect
In reply to this post by DearDaniel
DearDaniel wrote
When I add it to my code, error occurs but it didn't mentioned anything about the error.
What's the error?

DearDaniel wrote
Also, as a follow up question, what is the difference between unbinding and without unbinding?
OpenGL is a state machine.

When you execute a drawing command, such as glDrawElements then it will executed the program bound at that moment, it will draw to the framebuffer bound at that moment, it will use the vertex array bound at that moment and so on.

Unbinding is a way to reset that current pointer resource, setting it somehow to a null, although the driver and OpenGL implementation have some default specifications for cases when there is nothing bound.

However, unbinding it costs as much as binding in terms of performances, so in general if you want to crazy optimize your code, you shouldn't unbind resources.

But be aware that this is a double edge sword, it might be dangerous and introduce bugs. Take for example this case that happened to me:
- you init vbo, ibo and vao of object A, but you leave vao A bound
- after that, you init vbo, ibo and vao of object B, but when you need to upload the indices, you have to bound first the ibo of object B to gl_element_array_buffer.
- since vao A is still bound, then you will modify its status -> crash/bug when you will try to render A

So, better start first with a safe approach and then later optimize
Reply | Threaded
Open this post in threaded view
|

Re: glVertexAttribPointer and BindBuffer

DearDaniel
The error is as follow,


OpenGL Error(GL_INVALID_OPERATION): display
Exception in thread "main" java.lang.RuntimeException: com.jogamp.opengl.GLException: Caught Error: null on thread main-Display-.macosx_nil-1-EDT-1
        at jogamp.newt.DefaultEDTUtil.invokeImpl(DefaultEDTUtil.java:252)
        at jogamp.newt.DefaultEDTUtil.invoke(DefaultEDTUtil.java:165)
        at jogamp.newt.DisplayImpl.runOnEDTIfAvail(DisplayImpl.java:442)
        at jogamp.newt.WindowImpl.runOnEDTIfAvail(WindowImpl.java:2782)
        at jogamp.newt.WindowImpl.setVisible(WindowImpl.java:1330)
        at jogamp.newt.WindowImpl.setVisible(WindowImpl.java:1335)
        at com.jogamp.newt.opengl.GLWindow.setVisible(GLWindow.java:578)
        at DOGL.MainFrame.<init>(MainFrame.java:104)
        at DOGL.MainFrame.main(MainFrame.java:116)
Caused by: com.jogamp.opengl.GLException: Caught Error: null on thread main-Display-.macosx_nil-1-EDT-1
        at com.jogamp.opengl.GLException.newGLException(GLException.java:76)
        at jogamp.opengl.GLDrawableHelper.invokeGLImpl(GLDrawableHelper.java:1327)
        at jogamp.opengl.GLDrawableHelper.invokeGL(GLDrawableHelper.java:1147)
        at com.jogamp.newt.opengl.GLWindow.display(GLWindow.java:759)
        at jogamp.opengl.GLAutoDrawableBase.defaultWindowResizedOp(GLAutoDrawableBase.java:260)
        at com.jogamp.newt.opengl.GLWindow.access$200(GLWindow.java:119)
        at com.jogamp.newt.opengl.GLWindow$2.windowResized(GLWindow.java:141)
        at jogamp.newt.WindowImpl.consumeWindowEvent(WindowImpl.java:4383)
        at jogamp.newt.WindowImpl.sendWindowEvent(WindowImpl.java:4317)
        at jogamp.newt.WindowImpl.setVisibleActionImpl(WindowImpl.java:1306)
        at jogamp.newt.WindowImpl$VisibleAction.run(WindowImpl.java:1318)
        at com.jogamp.common.util.RunnableTask.run(RunnableTask.java:145)
        at jogamp.newt.DefaultEDTUtil$NEDT.run(DefaultEDTUtil.java:375)
Caused by: java.lang.Error
        at DOGL.MyListener.checkError(MyListener.java:181)
        at DOGL.MyListener.display(MyListener.java:95)
        at jogamp.opengl.GLDrawableHelper.displayImpl(GLDrawableHelper.java:692)
        at jogamp.opengl.GLDrawableHelper.display(GLDrawableHelper.java:674)
        at jogamp.opengl.GLAutoDrawableBase$2.run(GLAutoDrawableBase.java:443)
        at jogamp.opengl.GLDrawableHelper.invokeGLImpl(GLDrawableHelper.java:1293)
        ... 11 more
OpenGL Error(GL_INVALID_OPERATION): display
Exception in thread "main-Display-.macosx_nil-1-EDT-1" com.jogamp.opengl.GLException: Caught Error: null on thread main-Display-.macosx_nil-1-EDT-1
        at com.jogamp.opengl.GLException.newGLException(GLException.java:76)
        at jogamp.opengl.GLDrawableHelper.invokeGLImpl(GLDrawableHelper.java:1327)
        at jogamp.opengl.GLDrawableHelper.invokeGL(GLDrawableHelper.java:1147)
        at com.jogamp.newt.opengl.GLWindow.display(GLWindow.java:759)
        at jogamp.opengl.GLAutoDrawableBase.defaultWindowRepaintOp(GLAutoDrawableBase.java:215)
        at com.jogamp.newt.opengl.GLWindow.access$100(GLWindow.java:119)
        at com.jogamp.newt.opengl.GLWindow$2.windowRepaint(GLWindow.java:136)
        at jogamp.newt.WindowImpl.consumeWindowEvent(WindowImpl.java:4401)
        at jogamp.newt.WindowImpl.consumeEvent(WindowImpl.java:3372)
        at jogamp.newt.DisplayImpl.dispatchMessage(DisplayImpl.java:680)
        at jogamp.newt.DisplayImpl.dispatchMessage(DisplayImpl.java:707)
        at jogamp.newt.DisplayImpl.dispatchMessages(DisplayImpl.java:746)
        at jogamp.newt.DisplayImpl$7.run(DisplayImpl.java:672)
        at jogamp.newt.DefaultEDTUtil$NEDT.run(DefaultEDTUtil.java:347)
Caused by: java.lang.Error
        at DOGL.MyListener.checkError(MyListener.java:181)
        at DOGL.MyListener.display(MyListener.java:95)
        at jogamp.opengl.GLDrawableHelper.displayImpl(GLDrawableHelper.java:692)
        at jogamp.opengl.GLDrawableHelper.display(GLDrawableHelper.java:674)
        at jogamp.opengl.GLAutoDrawableBase$2.run(GLAutoDrawableBase.java:443)
        at jogamp.opengl.GLDrawableHelper.invokeGLImpl(GLDrawableHelper.java:1293)
        ... 12 more
Never Stop ... Learn more ... Be humble ...
Reply | Threaded
Open this post in threaded view
|

Re: glVertexAttribPointer and BindBuffer

elect
The error is GL_INVALID_OPERATION.

Now add several checkError() calls among your code passing different texts to detect which is the exact call firing the error