【问题标题】:Using a single ByteBuffer with multiple arrays in OpenGL在 OpenGL 中使用带有多个数组的单个 ByteBuffer
【发布时间】:2013-01-10 10:22:55
【问题描述】:

在我的应用程序中,我必须使用 OpenGL 绘制多个元素,有些是三角形,有些是线条。每当我要绘制新形状时,我都会将我的顶点放入多个 float[] 并将我的索引放入多个 short[] 中。我还必须为每个新数组创建一个新的 FloatBufferShortBufferByteBuffer 以使其正常工作。

我怎样才能更有效地绘制多个元素?我正在考虑将所有顶点放入一个 float[] 并为每个元素创建一个新的 short[] 以删除多余的数组,但是是否可以使用一个 FloatBufferShortBuffer 并将所有数组变成一个单一的ByteBuffer,例如:

float[] vertices = { -3, -3, -3, 2, 3, 0, 2, -1, 0, 0, 5, 2, 3, 1 };
short[] indItemA = { 0, 1, 2, 0, 2, 3 };
short[] indItemB = { 4, 5, 6 };

FloatBuffer fBuff;
ShortBuffer sBuff;

ByteBuffer bBuff = ByteBuffer.allocateDirect(vertices.length * 4);
fbBuff.order(ByteOrder.nativeOrder());

fBuff = bBuff.asFloatBuffer();
fBuff.put(vertices);
fBuff.position(0);

sBuff = bBuff.asShortBuffer();
sBuff.put(indItemA);
sBuff.position(0);

sBuff.put(indItemB);
sBuff.position(0);

【问题讨论】:

    标签: android opengl-es bytebuffer


    【解决方案1】:

    glBufferData 将数据从缓冲区发送到显卡内存。你可以在调用之后对 ByteBuffer 做任何你想做的事情,它不会影响已经发送的数据。

    因此,如果您的目标是减少创建的 ByteBuffer 数量,您可以只创建一个用于所有内容的大型 ByteBuffer。只需重置缓冲区的指针,写入数据,发送到显卡并重复。

    // Do this once
    ByteBuffer bBuff = ByteBuffer.allocateDirect( someBigNumber );
    bBuff.order(ByteOrder.nativeOrder());
    FloatBuffer fBuff = bBuff.asFloatBuffer();
    ShortBuffer sBuff = bBuff.asFloatBuffer();
    
    // Do this for each shape
    fBuff.position(0);
    fBuff.put(vertices);
    fBuff.position(0);
    
    glBindBuffer( GL_ARRAY_BUFFER, vertexbuffer );
    glBufferData( GL_ARRAY_BUFFER, vertices.length * 4, fBuff, GL_STATIC_DRAW );
    
    sBuff.position( 0 );
    sBuff.put( indices );
    sBuff.position( 0 );
    
    glBindBuffer( GL_ARRAY_BUFFER, indexbuffer );
    glBufferData( GL_ARRAY_BUFFER, indices.length * 2, sBuff, GL_STATIC_DRAW );
    

    如果您的顶点和索引数据是静态的,您可以将每个形状的顶点数据放入一个缓冲区对象中,并将所有索引数据放入另一个缓冲区对象中,然后使用 glVertexPointer 和 glIndexPointer 的偏移参数来指定缓冲区对象中的位置数据开始。

    听起来您在运行时生成自定义形状,因此您可以重复使用 ByteBuffer 并将每个形状存储在单独的缓冲区对象中,如上面的示例。

    【讨论】:

    • 完美运行!我必须在每个glBindBufferglBufferData 以及对GL_ARRAY_BUFFERGL_STATIC_DRAW 的调用之前添加GLES11.,但除此之外,一切都完全按照我的意愿工作。只是好奇,这是保留内存和 CPU/GPU 使用率的最有效方法吗?
    • 做某事的“最有效”方式很大程度上取决于尝试做的事情。例如,如果您每帧创建一个 ByteBuffer 以将数据上传到图形卡,那么这将更有效率。真正了解的唯一方法是针对您的特定目的使用不同的方法进行基准测试。
    • 我的目的是最初绘制一个大数组或顶点和索引,但在活动的整个生命周期内都不会改变。
    • 好的,所以只需在应用程序开始时将所有顶点和索引数据加载到大型缓冲区对象中。请勿在每次要绘制形状时上传此数据。相反,您使用 glVertexPointer 的 offset 参数来指定形状数据在缓冲区中的位置。这种方法非常有效。
    猜你喜欢
    • 2020-01-07
    • 2013-03-28
    • 2020-09-12
    • 1970-01-01
    • 2011-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多