1

Collada (.dae ファイル) を読み込んでいますが、モデルには 2 つのオブジェクトがあります。1つ目は水色の素材で頂点が多い布です。そして2つ目は、布が落ちるときに折りたたまれるはずの箱です。

これは 250 フレームのアニメーションのはずですが、実際にそうであるかどうかはわかりません。それをAssimpにロードするaiScene*HasAnimation() == 0...また、布のメッシュに色がないとHasVertexColors() == 0表示され、エクスポートすることをもう一度検討する必要があるのではないかと心配しています。わからない、多分あなたは言うことができますか?この投稿には大きすぎるため、外部側にリンクします。(そのために残念)

Falling Cloth (Collada animation .dae): http://pastebin.com/54LkKq8k

私の問題は、水色の布が見えず、箱が黒いこと(0, 0, 0)です...

VBO の初期化:

void AssimpMesh::initMesh(aiMesh *mesh, MeshData *data) {
    //Buffer for temporary storage of new ids
    GLuint id;

    //Make vertex array
    glGenVertexArrays(1, &id);
    data->meshArray = id;

    //Tell OpenGL to use this array
    glBindVertexArray(id);

    //Assign vertices
    if (mesh->HasPositions()) {
        //Make buffer
        glGenBuffers(1, &id);
        data->buffers.push_back(id);
        data->bufferNames.push_back("Positions");

        //Set buffer data
        glBindBuffer(GL_ARRAY_BUFFER, id);
        glBufferData(GL_ARRAY_BUFFER, sizeof(aiVector3D) * mesh->mNumVertices, &mesh->mVertices[0], GL_STATIC_DRAW);

        //Set shader attribute data
        glEnableVertexAttribArray(VBO_VERTEX);
        glVertexAttribPointer(VBO_VERTEX, 3, GL_FLOAT, GL_FALSE, NULL, NULL);
    }

    //Assign colors
    if (mesh->HasVertexColors(0)) {
        //Make buffer
        glGenBuffers(1, &id);
        data->buffers.push_back(id);
        data->bufferNames.push_back("Colors");

        //Set buffer data
        glBindBuffer(GL_ARRAY_BUFFER, id);
        glBufferData(GL_ARRAY_BUFFER, sizeof(aiColor4D) * mesh->mNumVertices, &mesh->mColors[0], GL_STATIC_DRAW);

        //Set shader attribute data
        glEnableVertexAttribArray(VBO_COLOR);
        glVertexAttribPointer(VBO_COLOR, 4, GL_FLOAT, GL_FALSE, NULL, NULL);
    }

    //Assign texture coords
    if (mesh->HasTextureCoords(0)) {
        //Make buffer
        glGenBuffers(1, &id);
        data->buffers.push_back(id);
        data->bufferNames.push_back("TextureCoords");

        //Set buffer data
        glBindBuffer(GL_ARRAY_BUFFER, id);
        glBufferData(GL_ARRAY_BUFFER, sizeof(aiVector3D) * mesh->mNumVertices, &mesh->mTextureCoords[0], GL_STATIC_DRAW);

        //Set shader attribute data
        glEnableVertexAttribArray(VBO_TEXCORD);
        glVertexAttribPointer(VBO_TEXCORD, 3, GL_FLOAT, GL_FALSE, NULL, NULL);
    }

    //Assign colors
    if (mesh->HasNormals()) {
        //Make buffer
        glGenBuffers(1, &id);
        data->buffers.push_back(id);
        data->bufferNames.push_back("Normals");

        //Set buffer data
        glBindBuffer(GL_ARRAY_BUFFER, id);
        glBufferData(GL_ARRAY_BUFFER, sizeof(aiVector3D) * mesh->mNumVertices, &mesh->mNormals[0], GL_STATIC_DRAW);

        //Set shader attribute data
        glEnableVertexAttribArray(VBO_NORMAL);
        glVertexAttribPointer(VBO_NORMAL, 3, GL_FLOAT, GL_FALSE, NULL, NULL);
    }

    if (mesh->HasFaces()) {
        vector <unsigned int> indices;
        aiFace face;
        for (int i = 0; i < mesh->mNumFaces; i++) {
            face = mesh->mFaces[i];
            for (int j = 0; j < face.mNumIndices; j++) {
                indices.push_back(face.mIndices[j]);
            }
        }

        //Make buffer
        glGenBuffers(1, &id);
        data->buffers.push_back(id);
        data->bufferNames.push_back("Faces");

        //Set buffer data
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, id);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * indices.size(), &indices.front(), GL_STATIC_DRAW);
    }

    //Unbind vertex array
    glBindVertexArray(NULL);
}

描画モデル:

void AssimpMesh::draw() {
    //Draw all vertex arrays
    aiMesh *mesh;
    aiFace face;
    MeshData *data;
    for (int i = 0; i < meshes.size(); i++) {
        mesh = scene->mMeshes[i];
        face = mesh->mFaces[0];
        data = meshes[i];

        //Tell OpenGL to use this array
        glBindVertexArray(data->meshArray);

        //Tell OpenGL which shader to use
        glUseProgram(data->program);

        //Draw the elements of the array
        glDrawElements(GL_TRIANGLES, face.mNumIndices * mesh->mNumFaces, GL_UNSIGNED_INT, 0);
    }

    //Unbind vertex array
    glBindVertexArray(NULL);

    //Unbind shader
    glUseProgram(NULL);
}

頂点シェーダー:

#version 120

attribute vec3 vertex;
attribute vec4 color;
attribute vec3 texCoord;
attribute vec3 normal;

uniform mat4 transform;

varying vec3 shared_color;
varying vec2 shared_texCoord;
varying vec3 shared_normal;

void main() {
    gl_Position = transform * vec4(vertex, 1.0);

    //Send data to fragment shader
    shared_color = color.xyz;
    shared_texCoord = texCoord.xy;
    shared_normal = (transform * vec4(normal, 0.0)).xyz;
}

フラグメント シェーダー:

#version 120

uniform sampler2D diffuse;
uniform int flagTexture;

varying vec3 shared_color;
varying vec2 shared_texCoord;
varying vec3 shared_normal;

void main() {
    vec4 color = vec4(shared_color, 1);
    vec4 texture = texture2D(diffuse, shared_texCoord);
    vec4 finalColor = color;

    if (flagTexture >= 1) {
        finalColor = vec4(mix(color.rgb, texture.bgr, texture.a), 1);
        //finalColor = color * texture;
    }

    float shade = 0;
    if (shade >= 1) {
        vec3 lightPosition = vec3(0, 0, -1);
        float shadowDarkness = 0.8;
        vec3 actualLightPos = vec3(-lightPosition.x, lightPosition.y, lightPosition.z);
        float lightStrength = clamp(dot(actualLightPos, shared_normal), 1 - shadowDarkness, 1.0);
        vec4 litColor = finalColor * lightStrength;
        finalColor = litColor;
    }

    gl_FragColor = finalColor;
}
4

3 に答える 3

1

1) それは機能しますか?

テストしましたか?割り当て解除が正しくないように見えますが、正しくレンダリングされるはずです。 glDelete*2 番目の引数としてポインターを受け取ります。フロント要素への参照を渡しています。

これを次のように変更します。

for (int i = 0; i < buffers.size(); i++) {
    glDeleteBuffers(buffers[i].size(), &buffers[i].front());
}

glDeleteVertexArrays(meshes.size(), &meshes.front());

2) いいですか?

これは非常に標準的なレンダリング ループであり、その速度はシェーダーの複雑さにほぼ完全に依存します。ただし、すべてのメッシュに対して新しいポインターを宣言するのではなく、ループの外側でポインターを宣言してから再割り当てするという変更を行います。

aiMesh *mesh;
for (int i = 0; i < meshes.size(); i++) {
    mesh = scene->mMeshes[i];

    //Tell OpenGL to use this array
    glBindVertexArray(meshes[i]);

    //Draw the elements of the array
    glDrawElements(GL_TRIANGLES, mesh->mNumFaces, GL_UNSIGNED_INT, 0);
}

3) 追加情報

それには、私が決してお勧めしない恐ろしい小さな数学ライブラリが含まれていますが、後で頂点や物事を処理するために知っておく必要があります (たとえば、後でバッファをマップするとき)。

したがって、GL_ARRAY_BUFFER保存されている頂点を変更するためにマップする場合は、次のようなものを使用する必要があります。

glBindVertexArray(the_vao);
aiVector3D *data = reinterpret_cast<aiVector3D*>(glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE));

// do all the changes!

glUnmapBuffer(GL_ARRAY_BUFFER);
于 2014-04-24T00:21:56.373 に答える