加载OBJ文件时出现分段错误

问题描述 投票:0回答:1

在将这段代码添加到我的OpenGL程序后,我使用gcc在C ++中得到了“分段错误(内核已转储)”

vector<GLfloat> vecTofloat(vector<glm::vec3> veca){
    vector<GLfloat> fa;
    for (int i = 0; i < veca.size(); i++){
        glm::vec3 vec = veca[i];
        fa.push_back(vec.x);
        fa.push_back(vec.y);
        fa.push_back(vec.z);
    }
    return fa;
}

vector<GLfloat> vecTofloat(vector<glm::vec2> veca){
    vector<GLfloat> fa;
    for (int i = 0; i < veca.size(); i++){
        glm::vec2 vec = veca[i];
        fa.push_back(vec.x);
        fa.push_back(vec.y);
    }
    return fa;
}

MeshInstance loadOBJ(const char* path, const char* texPath, int tw, int th){
    vector<glm::vec3> vert;
    vector<glm::vec3> tvert;
    vector<GLuint> ivert;
    vector<glm::vec3> norm;
    vector<glm::vec3> tnorm;
    vector<GLuint> inorm;
    vector<glm::vec2> tex;
    vector<glm::vec2> ttex;
    vector<GLuint> itex;

    FILE* file = fopen(path, "r");
    if (file == NULL){
        LOG_ERROR("Unable to load OBJ mesh.");
        exit(-1);
    }

    while(true){
        char start[128];

        int res = fscanf(file, "%s", start);

        if (res == EOF){
            break;
        } else if (strncmp(start, "v", strlen("v")) == 0){
            glm::vec3 vertex;
            fscanf(file, "%f %f %f\n", &vertex.x, &vertex.y, &vertex.z);
            tvert.push_back(vertex);
        } else if (strncmp(start, "vt", strlen("vt")) == 0){
            glm::vec2 tex;
            fscanf(file, "%f %f\n", &tex.x, &tex.y);
            ttex.push_back(tex);
        } else if (strncmp(start, "vn", strlen("vn")) == 0){
            glm::vec3 nrm;
            fscanf(file, "%f %f %f\n", &nrm.x, &nrm.y, &nrm.z);
            tnorm.push_back(nrm);
        } else if (strncmp(start, "f", strlen("f")) == 0){
            std::string vertex1, vertex2, vertex3;
            unsigned int vertexIndex[3], uvIndex[3], normalIndex[3];
            fscanf(file, "%d/%d/%d %d/%d/%d %d/%d/%d\n",&vertexIndex[0],&uvIndex[0],&normalIndex[0], &vertexIndex[1], &uvIndex[1], &normalIndex[1], &vertexIndex[2], &uvIndex[2], &normalIndex[2] );

            ivert.push_back(vertexIndex[0]);
            ivert.push_back(vertexIndex[1]);
            ivert.push_back(vertexIndex[2]);
            itex.push_back(uvIndex[0]);
            itex.push_back(uvIndex[1]);
            itex.push_back(uvIndex[2]);
            inorm.push_back(normalIndex[0]);
            inorm.push_back(normalIndex[1]);
            inorm.push_back(normalIndex[2]);
        }
    }

    for (int i = 0; i < ivert.size(); i+=3){
        unsigned int vertex = ivert[i];
        vert.push_back(tvert[vertex - 1]);
    }

    for (int i = 0; i < itex.size(); i+=3){
        unsigned int vertex = itex[i];
        tex.push_back(ttex[vertex - 1]);
    }

    for (int i = 0; i < inorm.size(); i+=3){
        unsigned int vertex = inorm[i];
        norm.push_back(tnorm[vertex - 1]);     
    }

    return LoadToVAO(vecTofloat(vert), ivert, vecTofloat(tex), texPath, tw, th);
}

它所做的只是加载一个obj文件。我知道这是由于访问已被删除的内存,但是我无法弄清楚程序中发生分段错误的位置。

编辑:我用gdb调试了程序,现在我得到了:

Starting program: /home/saroj/workspace/Rachaita3D/Rachaita3D step
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7ffff5120700 (LWP 11819)]

Thread 1 "Rachaita3D" received signal SIGSEGV, Segmentation fault.
0x0000555555565f66 in __gnu_cxx::new_allocator<glm::vec<2, float, (glm::qualifier)0> >::construct<glm::vec<2, float, (glm::qualifier)0>, glm::vec<2, float, (glm::qualifier)0> const&> (this=0x7fffffffdca0, __p=0x555555950a50, __args#0=...)                              
    at /usr/include/c++/8/ext/new_allocator.h:136
136             { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
c++ opengl segmentation-fault glm-math wavefront
1个回答
0
投票
OBJ文件不仅可以支持三角形,而且还可以支持由4个或更多顶点组成的多边形(所有平面)。您不应该在任何地方对3号进行硬编码,但也许可以跳过/忽略由2个顶点组成的“线”。

数据向量的大小可能不同于3。通常,顶点坐标是2分量,而不是3,尽管有时您会看到3甚至4分量。

© www.soinside.com 2019 - 2024. All rights reserved.