Hello,
What I need is basically to modify my vertex coordinates in the GPU, and copy back those modified coordinates to CPU’s VBO.
The point is that I prepare the shape of my mesh once on startup of my app in the GPU, copy back the coords to CPU, and from that point on I keep sending those coords back to GPU, where they might again be modified, but this time on an ad-hoc, user-input-dependant, basis.
I use the following function to copy back - transform feedback:
public void copyTransformToVertex()
{
ByteBuffer buffer = (ByteBuffer)GLES30.glMapBufferRange( GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, 0,
TRAN_SIZE*mNumVertices, GLES30.GL_MAP_READ_BIT);
if( buffer!=null )
{
FloatBuffer feedback = buffer.order(ByteOrder.nativeOrder()).asFloatBuffer();
feedback.get(mVertAttribs1,0,VERT1_ATTRIBS*mNumVertices);
mVBO1.updateFloat(mVertAttribs1);
}
else
{
int error = GLES30.glGetError();
Log.e("mesh", "failed to map tf buffer, error="+error); // INVALID_OPERATION here
}
GLES30.glUnmapBuffer(GLES30.GL_TRANSFORM_FEEDBACK);
}
Now, the above works. Works if I do it the first time. But recently I discovered that under some rare circumstances, I need to modify my shape one more time on the GPU and send the results back to the CPU again. So I call the very same function again and this time I get GL_ERROR 1282 - INVALID_OPERATION
.
So glMapBufferRange throws INVALID_OPERATION. Reading the spec,
GL_INVALID_OPERATION is generated for any of the following conditions:
The buffer is already in a mapped state.
Neither GL_MAP_READ_BIT or GL_MAP_WRITE_BIT is set.
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.
GL_MAP_FLUSH_EXPLICIT_BIT is set and GL_MAP_WRITE_BIT is not set.
it would seem like the only reason might be that the buffer is already in a mapped state - but I do Unmap the buffer the first time around, don’t I?