0

自分自身を描画するために必要なすべての情報を処理する Model という名前のクラスがあります。基本的には2つの方法があります:

1) コンストラクター - VBO、VAO、およびユニフォーム スタッフを作成および初期化します。2) Draw - VAO をバインドして Draw

私の問題は、glBufferData を使用して VBO を初期化することです。GPU メモリにアップロードされるはずのデータがそうではないことに気付きました!! gDebugger を使用してこれを確認しました。また、データをコンストラクタークラスの外側で再度送信しようとすると、すべてがうまくいくことがわかりました。私は何が欠けていますか???

Model のインスタンス化されたクラス オブジェクトはグローバル変数であり、テンプレート パラメーター V と M はそれぞれ vec4 と mat4 です。

Linux/Windows/NVIDIA/RADEON でもテストしましたが、同じ動作が発生します。#verson 400 を Shader と glew に使用、glm 数学ライブラリ。

コードは次のとおりです。

1) コンストラクター:

/** This constructor has 5 steps:
 *  1) Allocate variables
 *  2) Create, bind and Send vbo inf.
 *  3) Create, bind vao info
 *  4) Create mapping between Buffer and Attributes in GPU memory
 *  5) Get uniform variables location
 * 
 * */
template<class V, class M>
Model<V, M>::Model( GLuint size, GLuint program ){
    assert( size > 0 );

    /** BEG - 1) Allocate variables */
    /** beg - model variable initialization */
    this->vertex        = new vec4[ size ];
    this->numVertex     = size;

    this->color         = new vec4[ size ];
    this->numColor      = size;

    //this->element     => not initialized
    //this->numElem     => not initialized

    this->modelMatrix   = M(1); // Identity Matrix
    this->position      = V(0); // Orign

    // VBO - Vertex Buffer Object information
    this->vbo           = new GLuint[ this->numBuff ];
    this->vboSize       = this->numBuff;

    // VAO - Vexter Array Object information
    this->vao           = new GLuint[ 1 ];
    this->numVao        = 1;
    this->attrib        = new GLuint[ this->numBuff ];
    this->numAttrib     = this->numBuff;

    this->uniform       = new string[ this->numUni ];
    this->uniformLoc    = new GLuint[ this->numUni ];
    this->numUniform    = this->numUni;

    this->program       = program;

    //beg - Inittialization
    this->attrib[VERTEX]     = 0;
    this->attrib[COLOR]      = 1;

    this->uniform[0]         = string("modelMatrix");
    this->uniform[1]         = string("position");
    //end - Inittialization
    /** END - 1) Allocate variables */


    /** BEG - 2) Create, bind and Send vbo inf */
    // Create vbo identifier
    glGenBuffers( this->vboSize, this->vbo );
    Other<V>::checkError("glGenBuffers");

    // Bind Buffer
    glBindBuffer( GL_ARRAY_BUFFER, (this->vbo)[0] );
    Other<V>::checkError("glBindBuffer");

    // Send Data to buffer
    glBufferData(   GL_ARRAY_BUFFER, sizeof( (this->vertex)[0][0] ) * (this->vertex)[0].length() * (this->numVertex),
                    &(this->vertex[0][0]), GL_STATIC_DRAW);
    Other<V>::checkError("glBufferData");

    // Bind Buffer
    glBindBuffer( GL_ARRAY_BUFFER, (this->vbo)[1] );
    Other<V>::checkError("glBindBuffer");

    // Send Data to buffer
    glBufferData(   GL_ARRAY_BUFFER, sizeof( (this->color)[0][0] ) * (this->color)[0].length() * (this->numColor),
                    &(this->color[0][0]), GL_STATIC_DRAW);
    Other<V>::checkError("glBufferData");
    /** END - 2) Create, bind and Send vbo inf */


    /** BEG - 3) Create, bind and enable vao info */
    // Create vao identifier
    glGenVertexArrays( 1, this->vao );
    Other<V>::checkError("glGenVertexArrays");
    glBindVertexArray( (this->vao)[0] );
    Other<V>::checkError("glBindVertexArray");

    // Enable attributes
    for ( uint i=0; i<numAttrib; i++ ){
        glEnableVertexAttribArray( i );
        Other<V>::checkError("glEnableVertexAttribArray");
    }
    /** END - 3) Create and enable vao info */


    /** BEG - 4) Create mapping between Buffer and Attributes in GPU memory */
    for ( uint i=0; i<numAttrib; i++ ){
        glBindBuffer( GL_ARRAY_BUFFER, (this->vbo)[i] );
        Other<V>::checkError("glBindBuffer");
        glVertexAttribPointer( (this->attrib)[i], (this->vertex)[i].length(), GL_FLOAT, GL_FALSE, 0, (GLubyte *)NULL);
        Other<V>::checkError("glBindBuffer");
    }
    /** END - 4) Create mapping between Buffer and Attributes in GPU memory */


    /** BEG - 5) Get uniform variables location */
    for ( uint i=0; i<numAttrib; i++ ){
        this->uniformLoc[i] = glGetUniformLocation( program, this->uniform[i].c_str() );
        Other<V>::checkError("glGetUniformLocation");
    }
    /** END - 5) Get uniform variables location */
}

2) 描く

template<class V, class M>
void Model<V, M>::draw()
{
    //glUniformMatrix4fv( this->uniformLoc[0], 1, GL_FALSE, &(this->modelMatrix[0][0]) );
    //glUniform4fv(       this->uniformLoc[1], 1, &(this->position[0]) );

    glBindVertexArray( (this->vao)[0] );
    glDrawArrays( GL_LINE_STRIP, 0, this->numVertex);
}

コンストラクターの後で GPU にデータを「再送信」するには、sendData メンバー関数を使用します。

template<class V, class M>
void Model<V, M>::sendData()
{
    glBindBuffer( GL_ARRAY_BUFFER, (this->vbo)[0] );

    // Send Data to buffer
    glBufferData(   GL_ARRAY_BUFFER, sizeof( (this->vertex)[0][0] ) * (this->vertex)[0].length() * (this->numVertex),
                        &(this->vertex[0][0]), GL_STATIC_DRAW);
}

編集:sendDataメンバー関数を追加するのを忘れていました

4

2 に答える 2

0

レンダー コンテキストを取得する前にそのクラスをインスタンス化すると、静的イニシャライザなどのように動作しなくなります。

基本的に、有効なコンテキストで動作することを何らかの形で確認しない限り、OpenGL 操作をクラス コンストラクターに入れるべきではありません。これを行うには、有効な OpenGL コンテキストを別のクラスのインスタンスにカプセル化し、それをパラメーターとしてコンテキストで動作するコンストラクターに渡します。

于 2012-04-17T21:10:54.590 に答える
0

コンストラクターが呼び出される (呼び出される) 前に、有効な opengl コンテキストが設定されていますglewInit()か?

OpenGL 呼び出しで静的に定義されたオブジェクトがある場合、それらは main() の前に構築されるため失敗します。コンストラクターで opengl 呼び出しを使用するオブジェクトが必要な場合newは、コンテキストが初期化された後にのみオブジェクトを作成するように注意する必要があります。

于 2012-04-17T20:49:12.773 に答える