2016-06-18 16 views
1

私は最近、thisウェブサイトから3DグラフィックスのOpenGLを学び始めました。私はこのライブラリのための長いチュートリアルがあることを理解しています。ほとんどのチュートリアルでは、glBegin()glEnd()というコマンドを使って図形を描きます。これは非常に簡単で、私の意見に従うのは簡単です。OpenGLの頂点配列バッファ描画の各機能は何をしますか?

しかし、これはおそらく時代遅れだと私は理解しており、私は代わりにglDrawArraysを使用しなければなりません。問題はこれです、私はちょうどこのメソッドを使用して描画するために必要なコード/概念を理解していません。コードは次のようになります。

void draw() { 
    //i get this bit 
    static const GLfloat g_vertex_buffer_data[] = { 
     -1.0f, -1.0f, 0.0f, 
     1.0f, -1.0f, 0.0f, 
     0.0f, 1.0f, 0.0f, 
    }; 

    //I stop getting it here 
    GLuint VertexArrayID; 
    glGenVertexArrays(1, &VertexArrayID); 
    glBindVertexArray(VertexArrayID); 
    GLuint vertexbuffer; 
    glGenBuffers(1, &vertexbuffer); 
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW); 
    glEnableVertexAttribArray(0); 
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); 
    glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,(void*)0); 
    glDrawArrays(GL_TRIANGLES, 0, 3); 
    glDisableVertexAttribArray(0); 
} 

誰かがこのコードを1行ずつ説明し、バッファの背後にある概念を説明することができますか。また、私は不思議です、古い描画コマンドはまだ新しいバージョンで動作しますか?もしそうなら、それを使用するのは悪い習慣ですか?

可能な限り単純な言葉ですべてを説明してください、私はこの科目の完全な初心者です。 TBH、私はバッファが何であるか知りません。

答えて

2

私はこれを私の簡単な理解で説明しますが、おそらくいくつかは間違っているでしょう。

古い関数は、削除されている/使用が推奨されていませんが、それでも下位互換性をサポートするようになっています。あなたはそれについてhereを読むことができます。私が知る限り、古いdeprecated関数はOpenGL ESやWebGLには存在しません。

バッファオブジェクトは、gpuにデータを格納するためにメモリを格納/割り当てするOpenGLオブジェクトです。あなたはそれについて読むことができます

glGenBuffers(1, &vertexbuffer); 

新しいバッファを生成/作成します。バッファにアクセスするために使用できる番号をvertexbufferに割り当てます。

glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); 

スタート使用(バインド)バッファvertexbuffer

glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW); 

メモリを割り当て、バインドさバッファのデータを設定します。 GL_STATIC_DRAWGL_DYNAMIC_DRAWGL_STREAM_DRAWは、最高のパフォーマンスのためにメモリをどこに格納するかをgpuに指示します。

glEnableVertexAttribArray(0); 

この0にある属性の使用を開始したGPUを教えてください。あなたがシェーダを使用している場合、あなたはあまり何もしない、それを2回バインドさGLint glGetAttribLocation(GLuint program, const GLchar *name);link

glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); 

でそれを得ることができます。それ以外の場所でバインドを解除するか、他のバッファーをバインドすることは除きます。

glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,(void*)0); 

これは、0にある属性の使用方法を設定します。これは、属性が次のように使用されることを意味します。すべての頂点に対して、きつく詰め込まれた(stride = 0、offset = 0)正規化する必要のない3つのfloat変数があります。

P.s:ストライドが3 * sizeof(GLfloat)であるべきではありませんか?編集:nvm、thisによると、それはうまくいくはずです。

編集:@Nicolボーラによると:

それは関数が呼び出された時点でGL_ARRAY_BUFFERに結合されたバッファオブジェクトを格納します。

編集: void glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid * pointer);。例:それはそれはそれはこれがあなたのシェーダを想定しているglVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*) (5 * sizeof(GLfloat)));

ようになる色についてglVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*) (3 * sizeof(GLfloat)));

ようになるCOORDテクスチャについてglVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*) (0 * sizeof(GLfloat)));

ようになる位置については Stride and pointer

0の位置、1のテクスチャ座標、およびcolor属性の位置は2です。

glDrawArrays(GL_TRIANGLES, 0, 3); 

バインドさ頂点バッファ(vertexbuffer)からオフセット0と3頂点を用いて三角形を描画するためにGPUに知らせます。

glDisableVertexAttribArray(0); 

0にある属性を使用して停止します。

頂点配列オブジェクト:

GLuint VertexArrayID; 

これは、それをアクセスするためのIDを格納し、前からvertexbufferと同じです。

glGenVertexArrays(1, &VertexArrayID); 

これも以前と同じように、新しい頂点配列を生成/作成します。

glBindVertexArray(VertexArrayID); 

頂点配列の使用/バインドを開始します。

ここで、vaoの説明が始まります。基本的にはこのオブジェクトはvbo(複数の場合もあります)とそれをどのように使用するのかを覚えています(glVertexAttribPointer()から)。これは一度だけ設定する必要があります。 vaoを使用していないときは、vboを​​バインド解除してバインドするたびに属性を再度設定する必要があります。 vaoを使うことによって、vaoを単にglBindVertexArray(GLuint vaoID);と呼ぶだけで簡単に結びつけることができます。それはあなたのためにすべてを助けます。したがって、vboを​​バインドしたり、属性を設定したり、その他すべてを行う必要はありません。代わりに、単にバオをバインドし、描画し、バオをアンバインドして、完了させます。


申し訳ありませんが、完全ではありません。

+1

'glVertexAttribPointer'の動作を説明するなら、関数呼び出し時に' GL_ARRAY_BUFFER'にバインドされたバッファオブジェクトを格納することを説明してください。 –

+0

実際にGreffin、その答えは本当に素晴らしかった、私はそれから多くの新しいことを学んだと私の理解は確かに増加している。他の誰かが答えを加えたいかどうかをしばらく待つつもりですが、 'glVertexAttribPointer(0,3、GL_FLOAT、GL_FALSE、0、(void *)0);'で少し霧が出ます。ありがとう、+1と私はおそらく後でそれを受け入れるでしょう。 –

+0

@AshwinGuptaどの部分がまだあなたのために霧がかかっていますか?それを使用する方法、または関数が呼び出されたときにgpuがどのように動作するのでしょうか?私はそれをどのように(ストライド、ptr)を使用するためのポストを更新しました。しかし、私はその部分で十分に経験していないので、それが呼び出されたときにどのようにGPUが動作するのか説明できません。 – Greffin28

関連する問題