7

私は現在、Superbible 5th edition に付属している GLTools クラスを使用しています。私は GLTriangleBatch クラスを探していますが、次のコードがあります:

// Create the master vertex array object
glGenVertexArrays(1, &vertexArrayBufferObject);
glBindVertexArray(vertexArrayBufferObject);


// Create the buffer objects
glGenBuffers(4, bufferObjects);

#define VERTEX_DATA     0
#define NORMAL_DATA     1
#define TEXTURE_DATA    2
#define INDEX_DATA      3

// Copy data to video memory
// Vertex data
glBindBuffer(GL_ARRAY_BUFFER, bufferObjects[VERTEX_DATA]);
glEnableVertexAttribArray(GLT_ATTRIBUTE_VERTEX);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*nNumVerts*3, pVerts, GL_STATIC_DRAW);
glVertexAttribPointer(GLT_ATTRIBUTE_VERTEX, 3, GL_FLOAT, GL_FALSE, 0, 0);

// Normal data
glBindBuffer(GL_ARRAY_BUFFER, bufferObjects[NORMAL_DATA]);
glEnableVertexAttribArray(GLT_ATTRIBUTE_NORMAL);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*nNumVerts*3, pNorms, GL_STATIC_DRAW);
glVertexAttribPointer(GLT_ATTRIBUTE_NORMAL, 3, GL_FLOAT, GL_FALSE, 0, 0);

// Texture coordinates
glBindBuffer(GL_ARRAY_BUFFER, bufferObjects[TEXTURE_DATA]);
glEnableVertexAttribArray(GLT_ATTRIBUTE_TEXTURE0);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*nNumVerts*2, pTexCoords, GL_STATIC_DRAW);
glVertexAttribPointer(GLT_ATTRIBUTE_TEXTURE0, 2, GL_FLOAT, GL_FALSE, 0, 0);

// Indexes
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferObjects[INDEX_DATA]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort)*nNumIndexes, pIndexes, GL_STATIC_DRAW);

// Done
glBindVertexArray(0);

// Free older, larger arrays
delete [] pIndexes;
delete [] pVerts;
delete [] pNorms;
delete [] pTexCoords;

// Reasign pointers so they are marked as unused
pIndexes = NULL;
pVerts = NULL;
pNorms = NULL;
pTexCoords = NULL;

私が理解していることから、コードはポインター pVerts、pNorms、pTexCoords、pIndexes の配列を渡し、それらを頂点バッファー オブジェクトの配列である頂点配列オブジェクトに格納します。これらは GPU のメモリに格納されます。その後、元のポインタは削除されます。

pVert が指す配列に保持されていた頂点位置にアクセスすることに興味があります。

今、私の質問は衝突検出を中心に展開しています。GLTriangleBatch のすべての頂点の配列にアクセスできるようにしたいと考えています。vertexBufferObject何らかの getter メソッドを使用して、後でそれらを取得できますか? pVerts ポインターを保持し、代わりに getter メソッドを使用するのが最善でしょうか? 将来的にGJK衝突検出アルゴリズムを実装したいので、パフォーマンスの面で考えています...

4

1 に答える 1

7

バッファオブジェクトは、頂点データのソースとして使用される場合、レンダリングの利益のために存在します。パフォーマンスの観点から、逆方向に進む(データを読み戻す)ことは一般的にお勧めできません。

glBufferDataに与えるヒントには、DRAW、READ、およびCOPYの3つのアクセスパターンがあります。これらは、バッファオブジェクトから直接データを取得/取得する方法をOpenGLに通知します。ヒントは、OpenGLがOpenGLとの間でどのように読み取り/書き込みを行うべきかを決定するものではありません。これらは単なるヒントです。APIは特定の動作を強制しませんが、それらに違反するとパフォーマンスが低下する可能性があります。

DRAWは、データをバッファに入れるが、そこから読み取ることはないことを意味します。READは、バッファーからデータを読み取るが、書き込みは行わないことを意味します(通常、変換フィードバックまたはピクセルバッファーの場合)。また、COPYは、バッファから直接読み取りも書き込みも行わないことを意味します。

「読み取りと書き込み」のヒントがないことに注意してください。「書く」、「読む」、「どちらでもない」だけです。データをバッファに直接書き込んでから、そのバッファからの読み取りを開始することがどれほど優れているかについてのヒントを検討してください。

繰り返しになりますが、ヒントはユーザーがデータを直接取得または取得するためのものです。glBufferData、、glBufferSubDataおよびさまざまなマッピング関数はすべて書き込みをglGetBufferSubData行い、マッピング関数はすべて読み取りを行います。

いずれにせよ、あなたはこれをすべきではありません。クライアントで使用する必要がある場合は、位置データのコピーをクライアントメモリに保存してください。

また、一部のドライバーは使用上のヒントを完全に無視します。代わりに、使用するつもりであると言うのではなく、実際に使用する方法に基づいて、バッファオブジェクトを配置する場所を決定します。そのバッファから読み取りを開始すると、ドライバがバッファのデータをそれほど高速ではないメモリに移動する可能性があるため、これはさらに悪いことになります。GPUから移動したり、クライアントのメモリ空間に移動したりすることもできます。

ただし、これを行うことを主張する場合は、バッファオブジェクトからデータを読み取る方法が2つあります。glGetBufferSubDataの逆ですglBufferSubData。また、書き込みではなく読み取り用にバッファをいつでもマップできます。

于 2011-06-21T04:11:21.017 に答える