-2

遅い glBegin/glEnd 手法をあきらめた後、最終的に VBO を使用することにしました。何時間にもわたるフラストレーションの末、ようやくコンパイルすることができました。しかし、それはそれが機能するという意味ではありません。関数「CreateVBO」はエラーなしで実行されますが、呼び出されるとすぐにプログラムがクラッシュし、関数または関数glutMainLoop()も呼び出されません。Reshape()Render()

関数は次のCreateVBO()とおりです。

void CreateVBO()
{
    glGenBuffers = (PFNGLGENBUFFERSPROC)wglGetProcAddress("glGenBuffers");
    glBindBuffer=(PFNGLBINDBUFFERPROC)wglGetProcAddress("glBindBuffer");
    glBufferData=(PFNGLBUFFERDATAPROC)wglGetProcAddress("glBufferData");
    glDeleteBuffers=(PFNGLDELETEBUFFERSPROC)wglGetProcAddress("glDeleteBuffers");
    glMapBuffer=(PFNGLMAPBUFFERPROC)wglGetProcAddress("glMapBuffer");


    for(float i=0; i<lines*2; i++)
    {

        t_vertices.push_back(i/9000);
        t_vertices.push_back(5 * (((int)i%2)*2-1));
        t_vertices.push_back(20);

        vert_cols.push_back(0);
        vert_cols.push_back(255);
        vert_cols.push_back(0);


        t_indices.push_back((int)i);
    }

    glGenBuffers(1, &VertexVBOID);
    glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID);
    glBufferData(GL_ARRAY_BUFFER, sizeof(float)*t_vertices.size(), &t_vertices[0], GL_STATIC_DRAW);

    glGenBuffers(1, &IndexVBOID);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int)*t_indices.size(), NULL, GL_STATIC_DRAW);

    GLvoid * buf = glMapBuffer( GL_ARRAY_BUFFER, GL_WRITE_ONLY );

    memcpy( (void*)buf, &vert_cols[0], (size_t)(sizeof(float)*vert_cols.size()));

    glBindBuffer( GL_ARRAY_BUFFER, 0 );
}

そして、ここにRender()関数があります。その関数を呼び出す前にプログラムがクラッシュするため、何が問題なのかわかりません。

void Display()
{
    glRotatef(1, 0, 1, 0);
    glClearColor(0, 0, 0, 0);
    glClear(GL_COLOR_BUFFER_BIT);

    glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID);
    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(t_vertices.size(), GL_FLOAT, 0, 0);   //The starting point of the VBO, for the vertices
    glEnableClientState(GL_COLOR_ARRAY);
    glColorPointer(vert_cols.size(), GL_FLOAT, 0, 0);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID);
    glDrawElements(GL_LINES, lines, GL_UNSIGNED_INT, 0);
    glutSwapBuffers();
    //Sleep(16);
    glutPostRedisplay();
}
4

1 に答える 1

1

あなたのコードは意味がありません。

まず、ベクトルvertexVBOIDを保持するのに十分な大きさを作成t_verticesし、正確にその配列で埋めます。次に、その VBO をマップし、その中のデータをベクターからのデータで上書きします。vert_color描画では、頂点位置と色属性の両方をメモリ内の同じ位置から取得するように指定します。これにより、色を位置として効果的に使用することもできます。

しかし、それはクラッシュの理由ではありません。実際には、クラッシュの主な理由は 2 つあります。

  1. インデックス配列を保持するのに十分な大きさを作成IndexVBOIDしますが、そのバッファーをいくつかのデータで初期化することはありません。代わりNULLにデータ ポインターとして指定するので、ストレージは作成されますが、初期化されません。したがって、そのバッファに未定義のコンテンツが残り、GL はそれを使用して描画するときに任意のメモリ位置にアクセスします。

  2. あなたglVertexPointerとのglColorPointer呼び出しは間違っています。最初のパラメーターは、配列のサイズでsizeはありません。これは、1、2、3、または 4 の単一の vectorのサイズです。配列のサイズはおそらく別のものであるため、この呼び出しはGL_INVALID_VALUEエラーを生成し、attrib ポインターをまったく設定しません。デフォルトでは、これらのポインターは NULL です。

したがって、最終的には、NULL ポインターに関連する未定義の配列インデックスから描画するように GL に要求しています。それはクラッシュする可能性が非常に高いです。一般に、これは未定義の動作であり、結果は何でもかまいません。

さらに、VertexVBOIDバッファをマップしたままにします。マップを解除することはありません。バッファーがマップされている限り、バッファーを GL コマンドのソースまたは宛先として使用することは無効です (永続的なマッピングが作成されない限り、これは比較的新しい機能であり、実際にはここには属しません)。

于 2015-11-24T20:39:07.900 に答える