【问题标题】:Animation in OpenGL using Assimp使用 Assimp 在 OpenGL 中制作动画
【发布时间】:2014-06-07 16:01:09
【问题描述】:

我最近发现有一个名为“Assimp”的库,用于导入可以在 c++ opengl 中渲染动画的模型,现在我试图弄清楚我必须做什么,才能加载纹理模型然后画出来……

1) 推荐从 Blender 导出动画的格式是什么?

2) 我已经有一个基本的网格类,正在绘制一个模型。我需要修改什么来支持动画?

我的数据结构:

struct ObjectData {
    vector <glm::vec3> vertices, normals, colors;
    vector <glm::vec2> texCoords;
    vector <GLuint> vIndices, uIndices, nIndices;
    vector <Material*> materials;
    glm::vec3 size, center;
};

我的网格 VBO 和绘图:

void Mesh::draw() {
    if (initialized) {
        shader->enable(true);

        if (texture != NULL) {
            texture->enable(true);
        }

        //Tell OpenGL which array to use
        glBindVertexArray(arrayObject);

        glDrawElements(renderMode, object->vIndices.size(), GL_UNSIGNED_INT, 0);

        glBindVertexArray(NULL);
        shader->enable(false);

        if (texture != NULL) {
            texture->enable(false);
        }
    }
}

void Mesh::updateVBO() {
    if (!initialized) {
        glGenVertexArrays(1, &arrayObject);
    }

    //Tell OpenGL which vertex array to use from now
    glBindVertexArray(arrayObject);

    if (!initialized) {
        glGenBuffers(VBO_COUNT, buffers);
        initialized = true;
    }

    //Set buffer data
    glBindBuffer(GL_ARRAY_BUFFER, buffers[VBO_VERTEX]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * object->vertices.size(), &object->vertices.front(), GL_STATIC_DRAW);

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

    if (object->colors.size()) {
        //Set buffer data
        glBindBuffer(GL_ARRAY_BUFFER, buffers[VBO_COLOR]);
        glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * object->colors.size(), &object->colors.front(), GL_STATIC_DRAW);

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

    if (object->texCoords.size()) {
        //Set buffer data
        glBindBuffer(GL_ARRAY_BUFFER, buffers[VBO_TEXCORD]);
        glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec2) * object->texCoords.size(), &object->texCoords.front(), GL_STATIC_DRAW);

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

    if (object->normals.size()) {
        //Set buffer data
        glBindBuffer(GL_ARRAY_BUFFER, buffers[VBO_NORMAL]);
        glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * object->normals.size(), &object->normals.front(), GL_STATIC_DRAW);

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

    //Set buffer data
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[VBO_INDEX]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * object->vIndices.size(), &object->vIndices.front(), GL_STATIC_DRAW);

    //Unbind vertex array
    glBindVertexArray(NULL);
}

【问题讨论】:

    标签: opengl animation assimp


    【解决方案1】:

    “开放资产导入库”有一个model viewer,您可以在其中预览具有所有受支持格式(包括动画)的模型。我建议将您的动画导出为各种格式,看看它们中是否有任何给您错误的结果(即渲染工件)并结束您自己的 awnser。就个人而言,尽管我使用的是 3ds Max,但我在 Collada (.dae) 方面取得了最大的成功。

    为了支持动画本身(可能是骨骼):在关键帧之间插入动画数据(aiNodeAnim);您需要根据插值动画数据计算骨骼矩阵(根据位置/旋转等创建矩阵);通过用影响它们的骨骼矩阵转换“顶点”(aiMesh/aiBone)来计算“动画”顶点;加权所有“动画顶点”并将它们加在一起;渲染新的顶点。这是动画的基本高级概述。

    有一些教程和书籍可以更深入地了解该主题。例如ogldev's tutorial 38Jason Gregory's Game Engine Architechture 有专门的动画章节。可以看一下assimps模型查看器的源码。

    【讨论】:

    • 我发现从 Blender 将动画导出为 COLLADA 并使用 Assimp 导入时存在一些问题(骨骼旋转看起来不正确)。由于这些问题是在我将同一个文件重新导入 Blender 时出现的,我认为它们是导出器中的错误。
    猜你喜欢
    • 2015-04-20
    • 1970-01-01
    • 2023-04-04
    • 2014-08-06
    • 2017-07-22
    • 1970-01-01
    • 2018-09-12
    • 2014-06-10
    • 2016-12-29
    相关资源
    最近更新 更多