3

これは私が三角形の配列を作る方法です

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

1 に答える 1

5

人々が使用する理由ByteBuffer.allocateDirect()は、 などの他のバッファ クラスにはメソッドFloatBufferがないためです。ダイレクト バッファとしてallocateDirect()のみ割り当てることができます。ByteBufferしたがってByteBuffer、 を割り当ててからメモリを として使用するFloatBufferことが、 を直接割り当てられる唯一の方法FloatBufferです。

ダイレクトバッファとは?

クラスのドキュメントでisDirect()は、次のFloatBufferように説明されています。

このバッファーが直接かどうかを示します。ダイレクト バッファは、ネイティブ メモリ API を最大限に活用しようとしますが、Java ヒープにとどまらない可能性があるため、ガベージ コレクションの影響を受けません。

フロート バッファがバイト バッファに基づいており、バイト バッファがダイレクトである場合、フロート バッファはダイレクトです。

つまり、ネイティブ バッファは、Java が干渉しないネイティブ メモリ割り当てです。

ダイレクト バッファーが必要になるのはいつですか?

奇妙なことに、これに関する明確なドキュメントを見つけることができませんでした。というわけで、以下は私が実験で確認した仮説ですが、これまでのところ反例は見つかりませんでした。

呼び出しが返された後、メモリが OpenGL 実装によって使用される OpenGL API にバッファが渡される場合、ダイレクト バッファ使用する必要があります。

私が見つけることができる唯一の例があります: クライアント側の頂点配列 (ところで、これらは 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 は元のバッファーにアクセスできません。したがって、ダイレクト バッファを使用する必要はありません。

于 2014-12-02T07:06:13.117 に答える