Hi guys i have a cube drawed using opengles. Every time that i call redraw function i update the coordinates_buffer using this code
floatBuffer.position(0);
floatBuffer.put(coordinates);
floatBuffer.position(0);
The problem is that on different devices (most of them have a api version 22 or upper) the first element is not update so i can see the rest of vertices that move while the first stays at first position. Another problem is that sometimes happened a java.nio.BufferOverflowException when i put the coordinates. I think that the mistakes stay on these line of code that are called 60 times for second.
Thanks to all indeed.
Well I had similar issue with the exception java.nio.BufferOverflowException. I was using this OpenGL library which is very easy to use and has a lot of premade shapes like: Circle, Rectangles, Images, Triangles and many more.
I was generating new coordinates for multiple images at the OnTouch event using the Images class and I got the exception error seemingly random at the
*updateBuffers() method.
fun updateBuffers() {
// init buffer for vertices
var byteBuffer: ByteBuffer = ByteBuffer.allocateDirect(coordinatesOpenGL.size * 4)
byteBuffer.order(ByteOrder.nativeOrder())
vertexBuffer = byteBuffer.asFloatBuffer()
vertexBuffer.put(coordinatesOpenGL)
vertexBuffer.position(0)
...
}
The obvious reason was that by the time we allocate the size of the byte buffer with the method ByteBuffer.allocateDirect() using the size of the array coordinatesOpenGL.size some change in the array size occurs. In single threaded environment that was unlikely to happen, so my conclusion at that time was, that there was another thread outside the OpenGL surface thread that was making calls to the method.
To find out if that was the case I Log the id and name of the current thread in the method, so when it was called I get a message. Here is the code to Log the id and name of current thread:
Log.i("msg", "${Thread.currentThread().id} ${Thread.currentThread().name}")
And then in the Log I saw that the main thread was also calling this method, and when it was called by multiple threads at the same time and both made changes to the ByteBuffer the overflow error occurs.
2020-12-16 05:54:12.461 26477-26516/com.slaviboy.test I/msg: 3074 GLThread 3074
2020-12-16 05:54:13.383 26477-26516/com.slaviboy.test I/msg: 3074 GLThread 3074
2020-12-16 05:54:13.401 26477-26516/com.slaviboy.test I/msg: 3074 GLThread 3074
2020-12-16 05:54:14.080 26477-26516/com.slaviboy.test I/msg: 3074 GLThread 3074
2020-12-16 05:54:14.097 26477-26477/com.slaviboy.test I/msg: 2 main
2020-12-16 05:54:14.098 26477-26516/com.slaviboy.test I/msg: 3074 GLThread 3074
2020-12-16 05:54:14.116 26477-26516/com.slaviboy.test I/msg: 3074 GLThread 3074
Then I realize that since I set the coordinate for the Images at the OnTouch event, the code was running on the main thread, so I had to wrap the code and execute it in the OpenGL surface thread.
Here is the code that I use to run the code at the OpenGL surface thread, instead in the main thread:
override fun onTouch(surfaceView: View, event: MotionEvent): Boolean {
if (surfaceView is GLSurfaceView) {
// run the code in the OpenGL surface thread
surfaceView.queueEvent(Runnable {
touch(event)
})
}
return consumedTouchEvent
}
So if had problem similar problem I suppose you first check if there is another Thread making the same call.