2011-01-19 9 views
2

OpenGLレッドブックの103ページに、buffer_objectを使用して何かを描画する方法の例(例2-17)を示します。OpenGL:描画にbuffer_objectsを使用する方法

#define BUFFER_OFFSET(bytes) ((GLubyte*) NULL + (bytes)) 


GLuint buffers[NUM_BUFFERS]; 

GLfloat vertices[][3] = { 
{ -1.0, -1.0, -1.0 }, 
{ 1.0, -1.0, -1.0 }, 
{ 1.0, 1.0, -1.0 }, 
{ -1.0, 1.0, -1.0 }, 
{ -1.0, -1.0, 1.0 }, 
{ 1.0, -1.0, 1.0 }, 
{ 1.0, 1.0, 1.0 }, 
{ -1.0, 1.0, 1.0 } 
}; 

GLubyte indices[][4] = { 
{ 0, 1, 2, 3 }, 
{ 4, 7, 6, 5 }, 
{ 0, 4, 5, 1 }, 
{ 3, 2, 6, 7 }, 
{ 0, 3, 7, 4 }, 
{ 1, 5, 6, 2 } 
}; 

glGenBuffers(NUM_BUFFERS, buffers); 
//Generate NUM_BUFFERS of buffers and put them in buffers array. 

glBindBuffer(GL_ARRAY_BUFFER, buffers[VERTICES]); 
//bind buffers 


glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); 
//allocate space for buffers 


glVertexPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0)); 

ここでは、どのアレイでデータを見つけるかを指定する配列を指すと仮定します。それはサーバーのいくつかのメモリアドレスへのポインタにする必要がありますか?

私はちょうどそのBUFFER_OFFSET(0)を理解していません。

これは、サーバーに常に1つのVertex_Arrayがあり、プログラムがそのアドレスを自動的に選択することを意味しますか? BUFFER_OFFSET(0)は、この配列でどこから開始するかを教えてくれるでしょう。?????????

glEnableClientState(GL_VERTEX_ARRAY); 

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[INDICES]); 

glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); 

glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, BUFFER_OFFSET(0)); 

ここでも同じです。最後のパラメータでアドレスを指定すると仮定します。しかし、私はBUFFER_OFFSET(0)が有用なアドレスであるとは思わない。

答えて

2
glVertexPointer(3, GL_FLOAT, 6 * sizeof(GLfloat), BUFFER_OFFSET(0)) 

最後のパラメータは、いくつかのメモリアドレスにないポイントを行います。とにかく直接ではありません。

「現在バインドされているバッファのオフセット0を使用する」と表示されます。

あなたは

glBindBuffer(GL_ARRAY_BUFFER, buffers[VERTICES]); 

と呼ばれる持っているので、これら2つのコール(第VertexPointerの第二の結合)の結合は、本質的に「ハンドルバッファである[VERTICES]、0によってオフセットバッファのアドレスを使用する」を意味します。

+0

ありがとうございます。 GL_ARRAY_BUFFERは常に1つしかありませんか?私は2つのGL_ARRAY_BUFFERsmをバインドすると言うと、バッファ[0]とバッファ[1]と言っています。どちらがプログラムを選択しますか? – NoviceCai

+0

@NoviceCai:* Pointer呼び出しを呼び出した時点でバインドされていたものを覚えています。そのため、BindBuffer(a)/ VertexPointer/BindBuffer(b)/ NormalPointerは頂点にバッファーaを使用し、通常の場合はbを使用します – Bahbar

+0

ありがとうございます。私もこのhttp://www.opengl.org/wiki/Vertex_Array_Objectを読んでいます – NoviceCai

1

バッファがバインドされている場合、glDrawElementsに与えられたそのポインタは、そのバッファへのオフセットとして扱われ、通常のポインタとしては扱われません。

元のARB_vertex_buffer_object拡張が同じ関数プロトタイプを使用したかったので、整数オフセットをポインタに変換する必要があるため、BUFFER_OFFSETが必要です。

さらに詳しい情報はOpenGL.org wikiをご覧ください。

+0

しかし、私は、この関数glVertexPointer(3、GL_FLOAT、6 * sizeof(GLfloat)、BUFFER_OFFSET(0))を意味します。最後のパラメータは、いくつかのメモリアドレスへのポインタです。しかし、BUFFER_OFFSET(0)はメモリアドレスではありません。少なくとも、通常のメモリアドレスではないので、混乱します。では、この関数が正しい配列を見つける方法は? – NoviceCai

1

インターリーブされたデータ、またはきつく詰め込まれていないバッファ内のデータがある場合は、オフセットが有効になります。 0のストライドは、密にパックされたデータを前提としています。ゼロのオフセットは、データがすぐに開始することをOpenGLに知らせます。一例を以下に示す。現在のメソッドを使用すると、頂点と法線のために別々のバッファが必要になります。ただし、そのデータをインターリーブすることができます:

normal.z

vertex.x、vertex.y、vertex.z、normal.x、normal.yを、そしてあなたは、バッファにそのデータを結合することができます。次に、バッファをバインドするようにOpenGLに指示するとき、ストライドとオフセットを知らせる必要があります。あなたがインターリーブされた頂点と正常なデータが含まれているfloatの配列を持っていると仮定すると、あなたの例では、

glGenBuffers(NUM_BUFFERS, buffers); 
glBindBuffer(GL_ARRAY_BUFFER, buffers[0]); 
glBufferData(GL_ARRAY_BUFFER, sizeof(interleaved_data), interleaved_data, GL_STATIC_DRAW); 
glVertexPointer(3, GL_FLOAT, 6 * sizeof(GLfloat), BUFFER_OFFSET(0)); 
glNormalPointer(3, GL_FLOAT, 6 * sizeof(GLfloat), BUFFER_OFFSET(3 * sizeof(GLfloat)); 

お知らせになる可能性がありストライドの値が連続したエントリの間に24のバイトがあることを示している6 *のはsizeof(GLfloat)であり、バッファ内に格納します。そして、通常のポインタのオフセットは3 * sizeof(GLfloat)であり、これは通常のデータがバッファの先頭から12バイトだけオフセットされていることを示します。

うまくいけば、これが役に立ちます。私が間違いをしたかどうかを教えてください。

+0

しかし、私はこの関数glVertexPointer(3、GL_FLOAT、6 * sizeof(GLfloat)、BUFFER_OFFSET(0))を意味します。最後のパラメータは、いくつかのメモリアドレスへのポインタです。しかし、BUFFER_OFFSET(0)はメモリアドレスではありません。少なくとも、通常のメモリアドレスではないので、混乱します。では、この関数が正しい配列を見つける方法は? – NoviceCai

+0

既に、glBindBufferで頂点オブジェクトをバインドしています。 glVertexPointerは、頂点位置に対してその配列の内容を使用する必要があることをOpenGLに知らせるだけです。 – Giawa

関連する問題