Can' get glMapBufferRange to work -> GL_INVALID_OPERATION

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

Can' get glMapBufferRange to work -> GL_INVALID_OPERATION

nyholku
I've got this trivial test code that I call inside  GLEventListener.display() the first time it is called
and I get GL_INVALID_OPERATION after the glMapBufferRange(), I've tried a various
combinations of the enums but no luck. Probably something trivial but this is my
first time in the VBO land.

        private javax.media.opengl.GL2 m_GL;

        public void test() {
                int FLOAT_SIZE_IN_BYTES = 4;
                int[] bufID = new int[1];
                float[] m_Data = { 0, 0, 0 };

                bufID = new int[1];
                m_GL.glGenBuffers(1, bufID, 0);
                System.err.printf("%04X\n", m_GL.glGetError());

                m_GL.glBindBuffer(m_GL.GL_ARRAY_BUFFER, bufID[0]);
                System.err.printf("%04X\n", m_GL.glGetError());
                m_GL.glBufferData(m_GL.GL_ARRAY_BUFFER, m_Data.length * FLOAT_SIZE_IN_BYTES, null, m_GL.GL_DYNAMIC_DRAW);
                System.err.printf("%04X\n", m_GL.glGetError());
                m_GL.glBindBuffer(m_GL.GL_ARRAY_BUFFER, 0);
                System.err.printf("%04X\n", m_GL.glGetError());

                m_GL.glBindBuffer(m_GL.GL_ARRAY_BUFFER, bufID[0]);
                System.err.printf("%04X\n", m_GL.glGetError());

                ByteBuffer vbb = m_GL.glMapBufferRange(m_GL.GL_ARRAY_BUFFER, 0, m_Data.length * FLOAT_SIZE_IN_BYTES, m_GL.GL_MAP_WRITE_BIT);
                System.err.printf("%04X\n", m_GL.glGetError());

                FloatBuffer vertexBuffer = vbb.asFloatBuffer();
                vertexBuffer.position(0);
                vertexBuffer.put(m_Data, 0, m_Data.length);
                m_GL.glUnmapBuffer(bufID[0]);

                m_GL.glBindBuffer(m_GL.GL_ARRAY_BUFFER, bufID[0]);
                m_GL.glEnableClientState(m_GL.GL_VERTEX_ARRAY);
                m_GL.glVertexPointer(3, m_GL.GL_FLOAT, 0, 0);
                m_GL.glDrawArrays(m_GL.GL_LINE_STRIP, 0, m_Data.length / 3);
                m_GL.glDisableClientState(m_GL.GL_VERTEX_ARRAY);
        }
Reply | Threaded
Open this post in threaded view
|

Re: Can' get glMapBufferRange to work -> GL_INVALID_OPERATION

gouessej
Administrator
Hi

At first, never store the GL instances, this is a bad practice and it can cause a lot of troubles.

Look at the documentation and maybe use glBufferStorage too:
http://www.opengl.org/sdk/docs/man/xhtml/glMapBufferRange.xml
http://www.opengl.org/sdk/docs/man/xhtml/glBufferStorage.xml

The documentation enumerates the possible causes of this error.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Can' get glMapBufferRange to work -> GL_INVALID_OPERATION

nyholku
Thanks.

Well I don't think temporarily storing a ref GL2 in local variable m_GL can have
any side effects because everything happens inside the display callback and
m_GL gets updated every time.

I'm not using glBufferStorage (should I, would tha be available on Android...?),
should I be using it?

I've stared at possible causes until eyes water and test my fingers to bone by I cannot
figure out what is the problem:

These are the possible causes:

> The buffer is already in a mapped state.

How could it be, I just created the buffer, I've also tried un mapping it but of course that gives error. How can I tell
the state of the buffer?

> Neither GL_MAP_READ_BIT or GL_MAP_WRITE_BIT is set.

Looks obvious to me that I have the GL_MAP_WRITE_BIT set this should no be the problem



> GL_MAP_READ_BIT is set and any of GL_MAP_INVALIDATE_RANGE_BIT, GL_MAP_INVALIDATE_BUFFER_BIT, or GL_MAP_UNSYNCHRONIZED_BIT is set.

I don't have that set, so this cannot be the problem.

> GL_MAP_FLUSH_EXPLICIT_BIT is set and GL_MAP_WRITE_BIT is not set.

I don't have that set either.

> Any of GL_MAP_READ_BIT, GL_MAP_WRITE_BIT, GL_MAP_PERSISTENT_BIT, or GL_MAP_COHERENT_BIT are included in access, but the same bit is not included in the buffer's storage flags.

What are buffer's storage flags and how can I set them?

br Kusti

Reply | Threaded
Open this post in threaded view
|

Re: Can' get glMapBufferRange to work -> GL_INVALID_OPERATION

gouessej
Administrator
Rather use GLContext.getCurrentGL() and only store GL instances into local variables, never in fields, in order to avoid using an invalid GL instance.

Are you sure that glMapBufferRange is supported by your hardware? Have you called this method to check that?
http://jogamp.org/deployment/jogamp-next/javadoc/jogl/javadoc/javax/media/opengl/GLBase.html#isFunctionAvailable(java.lang.String)
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Can' get glMapBufferRange to work -> GL_INVALID_OPERATION

nyholku
Thanks for the tip on getCurrentGL() I did not know about this, although in my case I'm pretty sure I cannot call invalid context by mistake.

I did:


                        System.out.println(m_GL.isFunctionAvailable("glMapBufferRange"));

and that outputs 'true'.

I'm at loss how to debug this further. If I could find a working self standing demo code I could work my way there but surprisingly after hours of wondering about this I have found none.
Reply | Threaded
Open this post in threaded view
|

Re: Can' get glMapBufferRange to work -> GL_INVALID_OPERATION

gouessej
Administrator
This post was updated on .
Do you really need glMapBufferRange in your case? Otherwise, you can create a direct NIO buffer. There are a few examples using this method and I don't think it's supported. Rather use GL2ES2 if you aim Android too.

What about that?
http://onrendering.blogspot.fr/2011/10/buffer-object-streaming-in-opengl.html
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Can' get glMapBufferRange to work -> GL_INVALID_OPERATION

nyholku
Well, I don't know if 'need it', I trivially converted my code to use VBO and that works, but it looked like there was a lot overhead (yeah, looked, no measurements) so I went on to investigate what is 'The Right Way' and actually found the very link you referred to, but that relies on, surprise surprise, on glMapBufferRange! I'm sure there are lots of different ways I can implement my code reasonably efficiently but glMapBufferRange and GL_MAP_UNSYNCHRONIZED_BIT seems such an elegant, simple and fast way that I wanted to pursue that. Especially as it looked almost trivial to implement. But I can't get that darn call to work....

Thanks for you support BTW.

br Kusti