重复调用 glBufferData 未能为新缓冲区分配内存
Repeates call glBufferData failed to allocate memory for new buffer
在渲染器的初始化中,VBO 被创建并绑定到 GL_ARRAY_BUFFER 或 GL_ELEMENTS_ARRAY_BUFFER,第一个有三个顶点。调用 glBufferData 将这三个顶点的属性缓存到 GPU。
如:
InitVBO() {
vboArray = new int[4];
GLES20.glGenBuffers(4, vboArray, 0);
poseBuf = ByteBuffer.allocateDirect(poseLength * Float.SIZE / Byte.SIZE).order(ByteOrder.nativeOrder()).asFloatBuffer();
UpdatePose(); // fill array data to FloatBuffer
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vboArray[VBO_VERTEX]);
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, poseLength * Float.SIZE / Byte.SIZE, poseBuf, GLES20.GL_DYNAMIC_DRAW); // poseBuf initialized capacity is 9 * 4
GLES20.glGetBufferParameteriv(GLES20.GL_ARRAY_BUFFER, GLES20.GL_BUFFER_SIZE, params, 0); // Get params[0] is 36
colorBuf = ByteBuffer.allocateDirect(colorLength * Float.SIZE / Byte.SIZE).order(ByteOrder.nativeOrder()).asFloatBuffer();
UpdateColor(); // fill array data to FloatBuffer
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vboArray[VBO_GRID_COLOR]);
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, colorLength * Float.SIZE / Byte.SIZE, gridColorBuf, GLES20.GL_DYNAMIC_DRAW);
...
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
}
然后,它在子线程中从 TCP Network Msg 接收顶点数据。顶点数超过三个。我记得 glBufferData:
UpdateVBO(){
poseBuf = ByteBuffer.allocateDirect(poseLength * Float.SIZE / Byte.SIZE).order(ByteOrder.nativeOrder()).asFloatBuffer();
UpdatePose(); // fill array data to FloatBuffer
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vboArray[VBO_VERTEX]);
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, poseLength * Float.SIZE / Byte.SIZE, poseBuf, GLES20.GL_DYNAMIC_DRAW); // poseBuf has been updated with capacity 12 * 4
GLES20.glGetBufferParameteriv(GLES20.GL_ARRAY_BUFFER, GLES20.GL_BUFFER_SIZE, pnew, 0); // get pnew[0] is 0
...
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
}
为什么 OpenGL ES 服务器不为新缓冲区分配内存?
我找到了答案。
我的程序的重大错误是我不应该在程序的子线程中更新缓冲区缓存。
如果我创建一个由子线程调用的函数来更新顶点poseBuf,并在draw函数中更新VBO缓存。这个问题就解决了。
在渲染器的初始化中,VBO 被创建并绑定到 GL_ARRAY_BUFFER 或 GL_ELEMENTS_ARRAY_BUFFER,第一个有三个顶点。调用 glBufferData 将这三个顶点的属性缓存到 GPU。 如:
InitVBO() {
vboArray = new int[4];
GLES20.glGenBuffers(4, vboArray, 0);
poseBuf = ByteBuffer.allocateDirect(poseLength * Float.SIZE / Byte.SIZE).order(ByteOrder.nativeOrder()).asFloatBuffer();
UpdatePose(); // fill array data to FloatBuffer
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vboArray[VBO_VERTEX]);
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, poseLength * Float.SIZE / Byte.SIZE, poseBuf, GLES20.GL_DYNAMIC_DRAW); // poseBuf initialized capacity is 9 * 4
GLES20.glGetBufferParameteriv(GLES20.GL_ARRAY_BUFFER, GLES20.GL_BUFFER_SIZE, params, 0); // Get params[0] is 36
colorBuf = ByteBuffer.allocateDirect(colorLength * Float.SIZE / Byte.SIZE).order(ByteOrder.nativeOrder()).asFloatBuffer();
UpdateColor(); // fill array data to FloatBuffer
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vboArray[VBO_GRID_COLOR]);
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, colorLength * Float.SIZE / Byte.SIZE, gridColorBuf, GLES20.GL_DYNAMIC_DRAW);
...
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
}
然后,它在子线程中从 TCP Network Msg 接收顶点数据。顶点数超过三个。我记得 glBufferData:
UpdateVBO(){
poseBuf = ByteBuffer.allocateDirect(poseLength * Float.SIZE / Byte.SIZE).order(ByteOrder.nativeOrder()).asFloatBuffer();
UpdatePose(); // fill array data to FloatBuffer
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vboArray[VBO_VERTEX]);
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, poseLength * Float.SIZE / Byte.SIZE, poseBuf, GLES20.GL_DYNAMIC_DRAW); // poseBuf has been updated with capacity 12 * 4
GLES20.glGetBufferParameteriv(GLES20.GL_ARRAY_BUFFER, GLES20.GL_BUFFER_SIZE, pnew, 0); // get pnew[0] is 0
...
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
}
为什么 OpenGL ES 服务器不为新缓冲区分配内存?
我找到了答案。
我的程序的重大错误是我不应该在程序的子线程中更新缓冲区缓存。
如果我创建一个由子线程调用的函数来更新顶点poseBuf,并在draw函数中更新VBO缓存。这个问题就解决了。