提问者:小点点

构造函数在退出函数时无法初始化一个参数


我反对我的C++代码中的一个问题。 我正在使用Assimp库,我有一个类,它有一个类型为const aiscene*的属性。 在类的构造函数中,我分配了这个值,所有工作都很正常,但是当我退出构造函数代码时,参数const aiscene*没有分配任何数据

我把密码贴在这里。

模型。H

class Model
{
public:
    Model(std::string objectLoc, std::string vertexLoc, std::string fragmentLoc,
    glm::vec3 position, glm::vec3 scale, glm::vec3 rotation,
    Camera* camera);

    void render();

    ~Model();

private:
    std::string objectLoc, vertexLoc, fragmentLoc;
    Shader* shader;
    glm::mat4 model;
    glm::vec3 position, scale, rotation;
    Camera* camera;

    std::vector<Mesh*> meshes;
    std::vector<Texture*> textures;

    std::vector<unsigned int> meshToTex;
    std::unordered_map<std::string, GLuint> boneMapping;
    std::vector<glm::mat4> bonesTransformations;

    const aiScene* scene;

    glm::mat4 globalInverseTransform;

    GLuint boneCount;
};

model.cpp

Model::Model(std::string objectLoc, std::string vertexLoc, std::string fragmentLoc, glm::vec3 
position, glm::vec3 scale, glm::vec3 rotation, Camera* camera)
: objectLoc(objectLoc), vertexLoc(vertexLoc), fragmentLoc(fragmentLoc),
position(position), scale(scale), rotation(rotation),
camera(camera),
boneCount(0)
{
    shader = new Shader(vertexLoc, fragmentLoc,
    DirectionalLight(glm::vec3(1.0f, 1.0f, 1.0f), 0.4f, 0.1f, glm::vec3(0.0f, 0.0f, -1.0f)),
    SpecularLight(1.0f, 250.0f),
    SpotLight(glm::vec3(1.0f, 1.0f, 1.0f), 0.0f, 1.0f, glm::vec3(0.0f, 0.0f, 0.0f), 1.0f, 0.0f, 0.0f, 
    glm::vec3(0.0f, 0.0f, -1.0f), glm::radians(10.0f)));

    shader->addPointLight(PointLight(glm::vec3(1.0f, 0.0f, 0.0f), 0.2f, 0.2f, glm::vec3(0.0f, 0.0f, 
-15.0f), 0.3f, 0.2f, 0.1f));
    shader->addPointLight(PointLight(glm::vec3(0.0f, 1.0f, 0.0f), 0.2f, 0.2f, glm::vec3(10.0f, 0.0f, 
-15.0f), 0.3f, 0.2f, 0.1f));
    shader->addPointLight(PointLight(glm::vec3(0.0f, 0.0f, 1.0f), 0.2f, 1.2f, glm::vec3(-10.0f, 0.0f, 
-15.0f), 0.8f, 0.2f, 0.1f));

    model = glm::translate(glm::mat4(1.0f), position)
        * glm::scale(glm::mat4(1.0f), scale)
        * glm::rotate(glm::mat4(1.0f), glm::radians(rotation.x), glm::vec3(1, 0, 0))
        * glm::rotate(glm::mat4(1.0f), glm::radians(rotation.y), glm::vec3(0, 1, 0))
        * glm::rotate(glm::mat4(1.0f), glm::radians(rotation.z), glm::vec3(0, 0, 1));

    Assimp::Importer importer;

    scene = importer.ReadFile(objectLoc,
        aiProcess_Triangulate |
        aiProcess_FlipUVs |
        aiProcess_GenSmoothNormals |
        aiProcess_JoinIdenticalVertices);

    if (!scene)
    {
        printf("Cannot load model %s: %s\n", objectLoc.c_str(), importer.GetErrorString());
        return;
    }

    aiNode* rootNode = scene->mRootNode;
    globalInverseTransform = aiMatrix4x4ToGlm(rootNode->mTransformation.Inverse());
    loadNode(rootNode);
    loadTextures();
}

我试过所有的东西,从一个一个复制属性到对象场景,到在所有涉及的类中做一个克隆的方法,但是什么都没有。 甚至,我认为问题可能出在场景属性中的const标识符上,但是如果我使对象不是常量,它的工作方式也会错误。

我不会在Model类的任何方法中修改该属性。

我在这里给你贴了一些问题的照片。

构造函数的良好效果

构造函数的错误结果

如果你能帮我,那就太好了。


共1个答案

匿名用户

文件上说

返回的数据是只读的,导入程序对象保留数据的所有权,并在销毁时将其销毁。

[Assimp::Importer::ReadFile]

当构造函数离开时,Assimp::Importer Importer;Scene所指向的对象将被销毁。

在离开构造函数或

使用GetOrphanedScene()获取它的所有权。

[Assimp::Importer::ReadFile]

Aiscene*Assimp::Importer::GetOrphanedScene()
返回上次成功调用ReadFile()加载的场景,并从Importer实例的所有权中释放该场景。

应用程序现在负责删除场景。 对GetScene()或GetOrphanedScene()的任何进一步调用都将返回NULL--直到通过ReadFile()加载了一个新场景。

返回:当前场景,如果当前没有加载场景,则返回NULL

注意:只有在万不得已的情况下,才能使用这种方法。 按照设计,Aiscene的只由Assimp而不是其他人维护,分配和释放。 这背后的原因是金科玉律,即释放应该始终由执行原始分配的模块执行,因为堆不一定是共享的。 GetOrphanedScene()强制您自己删除返回的场景,但只有当且仅当您使用与Assimp相同的堆时,这才是正确的。 在Windows上,只要所有内容都链接到运行时库的多线程DLL版本,则通常很好。 它同样适用于与assimp的静态链接。

[Assimp::Importer::GetOrphanedScene]