我正在使用OpenGL ES 2.0绘制一些对象,并且每个顶点都有几个属性,为了获得最佳性能,我将交错存储在单个缓冲区中。其中一些(如位置)用浮点数(GLES20.GL_FLOAT
)表示,但我传入一种颜色,将颜色属性作为四个浮点组件传递是浪费内存所以我想使用{ {1}}。其中四个将打包成一个32位字段。但是,我无法找到一种在GLES20.GL_UNSIGNED_BYTE
中存储这些内容的简单方法。例如。使用ByteBuffer
作为我要执行以下操作的颜色:
GL_FLOAT
这有效,但我使用128位来表示可以用32表示的颜色,这也会导致性能下降。所以我想做的是创建一个 void addVertex(float xpos, float ypos, int color) {
floatBuffer.put(xpos);
floatBuffer.put(ypos);
floatBuffer.put(Color.red(color) / 255f);
floatBuffer.put(Color.green(color) / 255f);
floatBuffer.put(Color.blue(color) / 255f);
floatBuffer.put(Color.alpha(color) / 255f);
}
并使用ByteBuffer
为它创建一个别名,并使用适合所存储类型的任何一个。像这样:
asFloatBuffer()
但是这不起作用,因为 void addVertices() {
byteBuffer = ByteBuffer.allocateDirect(vertexCount * VERTEX_STRIDE).order(ByteOrder.nativeOrder());
floatBuffer = byteBuffer.asFloatBuffer();
for(Vertex v : vertices)
addVertex(v.x, v.y, v.color);
}
void addVertex(float xpos, float ypos, int color) {
floatBuffer.put(xpos);
floatBuffer.put(ypos);
byteBuffer.put(Color.red(color));
byteBuffer.put(Color.green(color));
byteBuffer.put(Color.blue(color));
byteBuffer.put(Color.alpha(color)); }
创建了一个asFloatBuffer()
,它共享FloatBuffer
的底层存储,但保留了自己的位置索引。我必须手动跟踪位置并在存储任何内容之前更新每个位置,这很难看。
我还可以将属性拆分为单独的缓冲区,但是性能损失可能会超过收益。
关于如何以优雅,高效的方式做到这一点的任何想法?
答案 0 :(得分:1)
ByteBuffer
还有其他方法可用于将除byte
之外的其他数据类型以与机器无关的方式放入缓冲区。因此,不要将ByteBuffer
包裹在FloatBuffer
中,而是直接使用ByteBuffer
,并使用putFloat()
附加float
值:
void addVertex(float xpos, float ypos, int color) {
byteBuffer.putFloat(xpos);
byteBuffer.putFloat(ypos);
byteBuffer.put((byte)Color.red(color));
byteBuffer.put((byte)Color.green(color));
byteBuffer.put((byte)Color.blue(color));
byteBuffer.put((byte)Color.alpha(color));
}
答案 1 :(得分:-1)
您可以将颜色打包到一个浮点数并将其放入浮点缓冲区,或将位置拆分为字节并将它们放入字节缓冲区。
作为一个例子,这里是如何做前者:
假设0-255 int
s,首先将它们打包成一个int
:
int colorBits = a << 24 | b << 16 | g << 8 | r;
然后将其变为float
:
float floatColor = Float.intBitsToFloat(colorBits);
floatBuffer.put(floatColor);