The OpenGL wrappers take the data pointer passed in by those sorts of
methods using native GetDirectBufferAddress of the corresponding type
(int or float) and pass that pointer into the native gl method. That
only works correctly if it's a direct buffer.
I just checked android_opengl_GLES10.cpp and GLES11.cpp and found that
glTexImage2D and glBufferData use the same getPointer() method to get
to the data. That means that behavior should be the same.
Ultimately, the data comes from:
*array = (jarray) _env->CallStaticObjectMethod(nioAccessClass,
getBaseArrayID, buffer);
offset = _env->CallStaticIntMethod(nioAccessClass,
getBaseArrayOffsetID, buffer);
data = _env->GetPrimitiveArrayCritical(*array, (jboolean *)
0);
return (void *) ((char *) data + offset);
then the gl method is called, then the pointer is released.
Always use direct buffers when working with any aspect of OpenGL on
Android.
On Feb 24, 4:01 am, Clankrieger <[email protected]> wrote:
> As what I am aware of, VBOs do not need direct buffers (and indirect
> buffers might be handled faster), but this is just a detail. I also
> tried GL_FIXED but it did not make much difference for me. I assume
> that it gives performance gains only if you have a) static data that
> is converted to fixed format once and then re-rendered or b) do all
> calculations with fixed number precision (which is making things a lot
> more complicated and less readable when you need to update data). So I
> switched back to Float because I hat to convert most values to fixed
> before uploading them in GL calls.
>
> I wonder if your offsets are correct? Is _pos_size_bytes the correct
> offset? For safety, I would stick to non-interleaved arrays for
> testing. Also I'm not sure when to array-copying in the bufferdata
> call takes place - have you tried a glFlush call or a buffer rebind
> (bind VBO to 0 and the ID again) after all the buffering? Somebody
> with knowledge about the native part of of this buffering could help
> you better with this, I guess.
>
> T.
>
> On Feb 16, 8:43 pm, Viktor Linder <[email protected]> wrote:
>
>
>
> > As you say, the most likely explanation is that I have a bad pointer
> > being used somewhere. The thing is I have gone over this code a bunch
> > of times and tried lots of different checks and I just can't find
> > what's wrong.
> > Do you have any pointers on ways to debug the crash in the GL library?
>
> > I forgot to mention: I bind the array buffer to 0 after the call to
> > glDrawElements(), so any future draw calls that are not using VBOs
> > will not break. Also, I am not using VBOs for all draw calls.
>
> > You keep a different VBO for each channel; is using a single VBO for
> > several channels not allowed?
>
> > If its possible to use a single buffer that would reduce the needed
> > calls to glBindBuffer() and allowed interleaved data which would
> > improve cache locality.
>
> > Curious; did using GL_FIXED give a large performance gain?
>
> > Thanks for your help.
>
> > /Viktor
> > On 16 Feb, 21:25, Robert Green <[email protected]> wrote:
>
> > > You're probably pointing something to some bad memory location
> > > somewhere. I know you didn't post all of your real code so I can't
> > > really say for sure but it looks to me like you may be doing something
> > > wrong with your buffers. Here's how I do it:
>
> > > -- Load --
> > > GL11 gl11 = (GL11) gl;
> > > if (modelData.normals != null) {
> > > int[] vboIds = new int[5];
> > > gl11.glGenBuffers(5, vboIds, 0);
> > > vertexVBOId = vboIds[0];
> > > texVBOId = vboIds[1];
> > > normalVBOId = vboIds[2];
> > > indexVBOId = vboIds[3];
> > > lightmapVBOId = vboIds[4];
> > > } else {
> > > int[] vboIds = new int[4];
> > > gl11.glGenBuffers(4, vboIds, 0);
> > > vertexVBOId = vboIds[0];
> > > texVBOId = vboIds[1];
> > > indexVBOId = vboIds[2];
> > > lightmapVBOId = vboIds[3];
> > > }
> > > gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER,
> > > vertexVBOId);
> > > gl11.glBufferData(GL11.GL_ARRAY_BUFFER,
> > > modelData.vertices.length *
> > > 4, BufferUtil.createDirectIntBuffer(modelData.vertices),
> > > GL11.GL_STATIC_DRAW);
> > > gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, texVBOId);
> > > gl11.glBufferData(GL11.GL_ARRAY_BUFFER,
> > > modelData.tex.length * 4,
> > > BufferUtil.createDirectIntBuffer(modelData.tex), GL11.GL_STATIC_DRAW);
> > > if (modelData.normals != null) {
> > > gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER,
> > > normalVBOId);
> > > gl11.glBufferData(GL11.GL_ARRAY_BUFFER,
> > > modelData.normals.length *
> > > 4, BufferUtil.createDirectIntBuffer(modelData.normals),
> > > GL11.GL_STATIC_DRAW);
> > > }
> > > gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER,
> > > indexVBOId);
> > > gl11.glBufferData(GL11.GL_ELEMENT_ARRAY_BUFFER,
> > > modelData.indices.length * 2,
> > > BufferUtil.createDirectShortBuffer(modelData.indices),
> > > GL11.GL_STATIC_DRAW);
> > > if (hasLightMap) {
> > > gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER,
> > > lightmapVBOId);
> > > gl11.glBufferData(GL11.GL_ARRAY_BUFFER,
> > > lightMapModelData.tex.length * 4,
> > > BufferUtil.createDirectIntBuffer(lightMapModelData.tex),
> > > GL11.GL_STATIC_DRAW);
> > > }
> > > BaseRenderer.checkErrors(gl11);
> > > gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, 0);
> > > gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER,
> > > 0);
>
> > > -- Draw --
>
> > > // use VBOs
> > > gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER,
> > > vertexVBOId);
> > > gl11.glVertexPointer(3, GL10.GL_FIXED, 0, 0);
> > > if (modelData.normals != null) {
> > > gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER,
> > > normalVBOId);
> > > gl11.glNormalPointer(GL10.GL_FIXED, 0, 0);
> > > }
> > > gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER,
> > > texVBOId);
> > > gl11.glTexCoordPointer(2, GL10.GL_FIXED,
> > > 0, 0);
> > > //gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER,
> > > indexVBOId);
> > > // the main draw call
> > > gl11.glDrawArrays(GL11.GL_TRIANGLES, 0,
> > > vertexCount);
> > > //gl11.glDrawElements(GL10.GL_TRIANGLES,
> > > vertexCount,
> > > GL10.GL_UNSIGNED_SHORT, 0);
> > > // clean up
> > > gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, 0);
> > > //gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER,
> > > 0);
>
> > > This code draws without indices but the commented code for indices is
> > > there.
> > > I use fixed point coordinates for verts, normals and UVs. You'd want
> > > to change that to floats for what you're doing.
>
> > > On Feb 16, 1:42 pm, Viktor Linder <[email protected]> wrote:
>
> > > > I am having trouble with implementing VBOs for my game.
> > > > I get crashes at random when calling glDrawElements() directly after
> > > > glGenBuffers() / glBufferData().
> > > > The crashes disappear when I add printouts which leads me to believe
> > > > it might be a race condition between glBufferData() and
> > > > glDrawElements() of some sort.
> > > > Or I am doing something else that breaks it, but I can't see what.
>
> > > > Here's what I do:
>
> > > > ...
> > > > gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
> > > > gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
> > > > ...
> > > > if(geometry not in cache) {
> > > > gl11.glGenBuffers(1, _temp_handle, 0);
> > > > _geo_id = _temp_handle[0];
>
> > > > // produce text geometry to scratch buffer (allocated with
> > > > ByteBuffer.allocateDirect())
> > > > int off = DynamicBuffer.allocate(_buf_size_floats);
> > > > TextProducer.create_geometry(_font, _text, DynamicBuffer._buffer,
> > > > off);
>
> > > > // upload geometry
> > > > gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, _geo_id);
>
> > > > DynamicBuffer._buffer.position(off);
> > > > gl11.glBufferData(GL11.GL_ARRAY_BUFFER, _buf_size_bytes,
> > > > DynamicBuffer._buffer, GL11.GL_STATIC_DRAW);
>
> > > > DynamicBuffer.deallocate_last(_buf_size_floats);
>
> > > > // set vertex pointer
> > > > gl11.glVertexPointer(3, GL10.GL_FLOAT, 0, 0);
> > > > gl11.glTexCoordPointer(2, GL10.GL_FLOAT, 0, _pos_size_bytes);
>
> > > > insert_in_cache();} else {
>
> > > > ... bind + set vertex pointer using existing VBO ...
>
> > > > }
>
> > > > ...
> > > > gl.glDrawElements(); // <--- sometimes this call crashes, always after
> > > > buffer was just allocated/produced (ie the geometry-not-in-cache code
> > > > path)
> > > > ...
>
> > > > gl.glDisableClientState(VERTEX...);
> > > > gl.glDisableClientState(TEXCOORD...);
>
> > > > Sometimes the call to glDrawElements() crashes. The crash only happens
> > > > when glDrawElements() is called right after the buffer has been
> > > > allocated and written (ie "geometry not in cache" is true).
> > > > The crash seems more common if the produced buffer is a few kb or more
> > > > in size.
> > > > If I insert a Log.d() call in between glVertexPointer3f() and
> > > > glDrawElements() the crash goes away.
>
> > > > I have double checked that the GL calls are not setting the error
> > > > flag, and I am not writing past any buffer limit or feeding incorrect
> > > > sizes etc to glBufferData(). Note that everything renders correctly
> > > > without artifacts up to the crash. The crash does not happen for the
> > > > same geometry all the time, a piece of geometry can be produced and
> > > > rendered correctly, then be re-produced and crash.
>
> > > > Before I make a minimal reproducible example, I thought I would ask
> > > > this
>
> ...
>
> read more »
--
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en