5

私は現在、Superbible第5版に付属のGLToolsクラスを使用しています。 、私は、コードはポインタpVerts、pNorms、pTexCoords、pIndexes配列を渡し、頂点配列オブジェクトに格納し理解して何からOpenGL頂点バッファオブジェクト、衝突検出などの他の用途のために頂点データにアクセスできますか?

// 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; 

:私はGLTriangleBatchクラスで探していますし、それが次のコードを持っています本質的に頂点バッファオブジェクトの配列である。これらはGPUのメモリに保存されます。その後、元のポインタは削除されます。

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

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

答えて

7

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

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

DRAWは、データをバッファに格納することを意味しますが、読み込みはできません。 READは、バッファからデータを読み込みますが、書き込みはしません(通常、変換フィードバックやピクセルバッファ用)。そしてCOPYは、あなたがバッファから直接読み書きすることも、バッファに直接書き込むこともしないことを意味します。

「読み書き」のヒントはありません。 「書き込み」、「読み込み」、および「どちらもありません」があります。バッファに直接データを書き込んだ後、そのバッファから読み込みを開始するというアイデアの良さについてのヒントを考えてみましょう。

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

いずれにしても、この操作は行わないでください。クライアント上で位置データを使用する必要がある場合は、位置データのコピーをクライアントメモリ内に保存してください。

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

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

+1

ありがとうございました!その反応はとても役に立ちました! pVertポインタを後で頂点データにアクセスするようにします。 – kbirk

+0

@ user785259:ポインタを保持するだけでは十分ではありません。実際には、 'delete []'や 'free(...) 'ではなく、メモリを確保しておく必要があります。メモリを解放した後でも、ポインタはC内に残っている可能性があります。これは無効です。たぶんあなたはガベージコレクション言語から来ているでしょう、そして、ポインタを破棄することは、実際にメモリを解放することを意味します。そして、はい、これは正気な意味です。しかし、これはあなたが扱っているC++であり、このすべてのニックピッキングは避けられない必要性です。 – datenwolf

関連する問題