这就是我如何制作一个三角形数组
float[] tableVerticesWithTriangle = {
// triangle 1
0f, 0f, 9f, 14f, 0f, 14f,
// triangle 2
0f, 0f, 9f, 0f, 9f, 14f
};
这就是我在原生环境中分配块的方式
vertexData = ByteBuffer
.allocateDirect(
tableVerticesWithTriangle.length * BYTES_PER_FLOAT)
.order(ByteOrder.nativeOrder()).asFloatBuffer();
vertexData.put(tableVerticesWithTriangle);
答案 0 :(得分:4)
人们使用ByteBuffer.allocateDirect()
的原因是其他缓冲类(如FloatBuffer
)没有allocateDirect()
方法。只能将ByteBuffer
分配为直接缓冲区。因此,分配ByteBuffer
,然后将内存用作FloatBuffer
,是获得直接分配FloatBuffer
的唯一方法。
isDirect()
类FloatBuffer
的文档解释如下:
指示此缓冲区是否为直接缓冲区。直接缓冲区将尽最大努力利用本机内存API,它可能不会留在Java堆中,因此它不受垃圾收集的影响。
浮点缓冲区是直接的,如果它基于字节缓冲区并且字节缓冲区是直接的。
在其他(不太正式)的单词中,本机缓冲区是Java没有搞乱的本机内存分配。
奇怪的是,我从未能找到明确的文档。因此,以下假设是我通过实验证实的,到目前为止没有找到任何反例。
当缓冲区传递给OpenGL API时,使用直接缓冲区 ,在调用返回后,OpenGL实现使用内存。
我只能找到一个例子:客户端顶点阵列(BTW在ES 3.0中被标记为遗留功能,但仍然受支持)。这是具有以下签名的glVertexAttribPointer()
调用,它支持不使用VBO的顶点数组:
glVertexAttribPointer(int indx, int size, int type, boolean normalized,
int stride, Buffer ptr)
在这种情况下,OpenGL将在以后的绘制调用中从缓冲区中提取顶点数据,因此在调用返回后,OpenGL仍然可以访问缓冲区内容,并且可能会直接由GPU读取。
在所有其他情况下(同样根据我的假设),使用直接缓冲区不是必要的。例如,您可以执行以下操作:
float[] vertexData = {...};
GLES20.glBufferData(GL_ARRAY_BUFFER, vertexData.length * 4,
FloatBuffer.wrap(vertexData), GLES20.GL_STATIC_DRAW);
glBufferData()
调用在调用期间消耗数据,并且在调用返回后OpenGL无法访问原始缓冲区。因此,没有必要使用直接缓冲区。