如何在OpenGL ES的ByteBuffer中交错不同的类型

时间:2013-08-28 02:51:43

标签: android opengl-es opengl-es-2.0 bytebuffer

我正在使用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的底层存储,但保留了自己的位置索引。我必须手动跟踪位置并在存储任何内容之前更新每个位置,这很难看。

我还可以将属性拆分为单独的缓冲区,但是性能损失可能会超过收益。

关于如何以优雅,高效的方式做到这一点的任何想法?

2 个答案:

答案 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);