1

我正在使用 OpenGL ES 2.0 绘制一些对象,每个顶点都有几个属性,为了获得最佳性能,我将交错存储在单个缓冲区中。其中一些(比如位置)用GLES20.GL_FLOAT浮点数GLES20.GL_UNSIGNED_BYTE(其中四个将打包到一个 32 位字段中。但是我想不出一种简单的方法将这些存储在ByteBuffers. 例如,使用GL_FLOAT颜色我会执行以下操作:

    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);
    }

这可行,但我使用 128 位来表示可以用 32 表示的颜色,这也会导致性能下降。所以我想做的是创建一个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共享底层存储的a ByteBuffer,但维护自己的位置索引。在存储任何东西之前,我必须手动跟踪位置并更新每个位置,这很难看。

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

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

4

2 回答 2

1

ByteBuffer具有其他方法,可用于以byte与机器无关的方式将其他数据类型放入缓冲区中。因此,不要将 a 包装ByteBuffer在 a 中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));     
}
于 2013-08-29T01:37:12.413 回答
-1

You could either pack the color into one float and put that into the float buffer, or split the position into bytes and put them into the byte buffer.

As an example, here's how to do the former:

Assuming 0-255 ints, first pack them into one int:

int colorBits = a << 24 | b << 16 | g << 8 | r;

then make that into a float:

float floatColor = Float.intBitsToFloat(colorBits);
floatBuffer.put(floatColor);
于 2013-08-28T06:39:20.700 回答