1

私の呼び出しglBufferSubDataの間にデータを上書きしたり、何らかの形で壊したりしているようです。glDrawArrays私は、Nvidia GeForce GT520M CUDA 1GB 用の最新のドライバーを使用して、Windows 7 64 ビットで作業しています。

私は 2 つのモデルを持っており、それぞれにアニメーションがあります。モデルには 1 つのメッシュがあり、そのメッシュは同じ VAO に格納されます。また、それぞれに 1 つのアニメーションがあり、メッシュのレンダリングに使用されるボーン変換は同じ VBO に保存されます。

私のワークフローは次のようになります。

  • モデルの骨変換行列を計算する
  • を使用してボーン変換行列を opengl にロードしglBufferSubData、バッファをバインドします。
  • を使用してモデルメッシュをレンダリングしますglDrawArrays

1 つのモデルでは、これは機能します (少なくとも、ほとんどの場合、頂点間に奇妙なギャップが生じることがあります)。

ただし、複数のモデルでは、メッシュへのレンダリング呼び出し間でボーン変換マトリックス データが混同されているようです。

単一モデルのアニメーション ウィンドウ
2 つのモデルのアニメーション ウィンドウ

ボーン変換データを次のようにロードします。

void Animation::bind()
{
    glBindBuffer(GL_UNIFORM_BUFFER, bufferId_);
    glBufferSubData(GL_UNIFORM_BUFFER, 0, currentTransforms_.size() * sizeof(glm::mat4), &currentTransforms_[0]);
    bindPoint_ = openGlDevice_->bindBuffer( bufferId_ );
}

そして、メッシュを次のようにレンダリングします。

void Mesh::render()
{
    glBindVertexArray(vaoId_);
    glDrawArrays(GL_TRIANGLES, 0, vertices_.size());
    glBindVertexArray(0);
}

glFinish()への呼び出しの後にへの呼び出しを追加するとrender()、問題なく動作します。これは、何らかの理由で、あるアニメーションの変換行列データが次のアニメーションに「出血」していることを示しているようです。

これはどのように起こりますか?glBufferSubDataそのバッファが使用されている間に(つまり、glDrawArraysたとえば)呼び出すと、ブロックされるという印象を受けました。そうではありませんか?

この同じコードが Linux でも問題なく機能することは、言及しておく価値があるかもしれません。

注: 削除した以前の投稿に関連しています。

メッシュ読み込みコード:

void Mesh::load()
{
    LOG_DEBUG( "loading mesh '" + name_ +"' into video memory." );

    // create our vao
    glGenVertexArrays(1, &vaoId_);
    glBindVertexArray(vaoId_);

    // create our vbos
    glGenBuffers(5, &vboIds_[0]);

    glBindBuffer(GL_ARRAY_BUFFER, vboIds_[0]);
    glBufferData(GL_ARRAY_BUFFER, vertices_.size() * sizeof(glm::vec3), &vertices_[0], GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

    glBindBuffer(GL_ARRAY_BUFFER, vboIds_[1]);
    glBufferData(GL_ARRAY_BUFFER, textureCoordinates_.size() * sizeof(glm::vec2), &textureCoordinates_[0], GL_STATIC_DRAW);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);

    glBindBuffer(GL_ARRAY_BUFFER, vboIds_[2]);
    glBufferData(GL_ARRAY_BUFFER, normals_.size() * sizeof(glm::vec3), &normals_[0], GL_STATIC_DRAW);
    glEnableVertexAttribArray(2);
    glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, 0);

    glBindBuffer(GL_ARRAY_BUFFER, vboIds_[3]);
    glBufferData(GL_ARRAY_BUFFER, colors_.size() * sizeof(glm::vec4), &colors_[0], GL_STATIC_DRAW);
    glEnableVertexAttribArray(3);
    glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, 0, 0);

    if (bones_.size() == 0)
    {
        bones_.resize( vertices_.size() );
        for (auto& b : bones_)
        {
            b.weights = glm::vec4(0.25f);
        }
    }

    glBindBuffer(GL_ARRAY_BUFFER, vboIds_[4]);
    glBufferData(GL_ARRAY_BUFFER, bones_.size() * sizeof(VertexBoneData), &bones_[0], GL_STATIC_DRAW);
    glEnableVertexAttribArray(4);
    glVertexAttribIPointer(4, 4, GL_INT, sizeof(VertexBoneData), (const GLvoid*)0);
    glEnableVertexAttribArray(5);
    glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, sizeof(VertexBoneData), (const GLvoid*)(sizeof(glm::ivec4)));

    glBindVertexArray(0);
}

アニメーション UBO セットアップ:

void Animation::setupAnimationUbo()
{
    bufferId_ = openGlDevice_->createBufferObject(GL_UNIFORM_BUFFER, Constants::MAX_NUMBER_OF_BONES_PER_MESH * sizeof(glm::mat4), &currentTransforms_[0]);
}

Constants::MAX_NUMBER_OF_BONES_PER_MESH100 に設定されています。

OpenGlDevice

GLuint OpenGlDevice::createBufferObject(GLenum target, glmd::uint32 totalSize, const void* dataPointer)
{
    GLuint bufferId = 0;
    glGenBuffers(1, &bufferId);
    glBindBuffer(target, bufferId);

    glBufferData(target, totalSize, dataPointer, GL_DYNAMIC_DRAW);
    glBindBuffer(target, 0);

    bufferIds_.push_back(bufferId);

    return bufferId;
}
4

1 に答える 1