从OBJ加载时,为什么OpenGL不能显示此模型?

时间:2016-09-08 15:34:08

标签: c++11 opengl

我的整个项目可以在http://github.com/jep-dev/FOGL找到。它期望Linux环境和自述文件中的要求。

我编写了一个天真的Wavefront OBJ加载器并尝试使用OpenGL绘制结果。我还创建了一个网格,它成功地在屏幕中心显示为一个球体。我可以将网格序列化为OBJ并成功加载它(请参阅test / src / model.cpp) - 但是不会显示加载的OBJ。除了这个方法与我显示网格的方式几乎相同之外,我无法想出除了用于显示OBJ的方法以外还有什么方法可以排除故障。

显示网格:

using namespace Model;
mesh_t mesh(150, 150,
[](float s, float t, std::vector<float> &vertices) {
    using namespace Math;
    auto theta = s*M_PI*2, phi = t*M_PI;
    vertices.emplace_back(cos(theta)*sin(phi)); // X
    vertices.emplace_back(sin(theta)*sin(phi)); // Y
    vertices.emplace_back(cos(phi));            // Z
});

glGenBuffers(1, &viewer.ids[view::e_id_vbuf]);
glBindBuffer(GL_ARRAY_BUFFER, viewer.ids[view::e_id_vbuf]);
glBufferData(GL_ARRAY_BUFFER, mesh.vertices.size() * sizeof(float),
    (void*) &mesh.vertices[0], GL_STATIC_DRAW);

glGenBuffers(1, &viewer.ids[view::e_id_fbuf]);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
    viewer.ids[view::e_id_fbuf]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, mesh.faces.size() * sizeof(int),
    (void*) &mesh.faces[0], GL_STATIC_DRAW);
viewer.nTriangles = mesh.faces.size()/3;

显示OBJ:

using namespace Model;
        obj_t object;
        auto status = obj_t::load(this -> mpath, object);
        if(status != obj_t::e_ok) {
            errors.push_back("The model failed to load.");
            return alive = false;
        }

        // TODO Use more than first range of each obj type
        if(object.v_beg.size() == 0) {
            errors.push_back("The loaded model does not contain vertices.");
            return alive = false;
        } else {
            auto v0 = object.v_beg[0], v1 = object.v_end[0];
            glGenBuffers(1, &viewer.ids[view::e_id_vbuf]);
            glBindBuffer(GL_ARRAY_BUFFER, viewer.ids[view::e_id_vbuf]);
            glBufferData(GL_ARRAY_BUFFER, v1-v0,
                    (void*)(&object.floats[v0]), GL_STATIC_DRAW);
        }
        if(object.vn_beg.size() != 0) {
            auto vn0 = object.vn_beg[0], vn1 = object.vn_end[0];
            glGenBuffers(1, &viewer.ids[view::e_id_vnbuf]);
            glBindBuffer(GL_ARRAY_BUFFER, viewer.ids[view::e_id_vnbuf]);
            glBufferData(GL_ARRAY_BUFFER, (vn1-vn0)*sizeof(float),
                    (void*)(&object.floats[vn0]), GL_STATIC_DRAW);
        }
        glGenBuffers(1, &viewer.ids[view::e_id_fbuf]);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
                viewer.ids[view::e_id_fbuf]);
        int f0, f1;
        if(object.f0_beg.size() != 0) {
            f0 = object.f0_beg[0];
            f1 = object.f0_end[0];
        } else if(object.f1_beg.size() != 0) {
            f0 = object.f1_beg[0];
            f1 = object.f1_end[0];
        } else if(object.f2_beg.size() != 0) {
            f0 = object.f2_beg[0];
            f1 = object.f2_end[0];
        } else if(object.f3_beg.size() != 0) {
            f0 = object.f3_beg[0];
            f1 = object.f3_end[0];
        } else {
            errors.push_back("The loaded model does not contain faces.");
            return alive = false;
        }
        viewer.nTriangles = (f1-f0)/3;
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, viewer.nTriangles*sizeof(int),
                (void*)(&object.ints[f0]), GL_STATIC_DRAW);

额外的代码用于范围提取,因为OBJ文件可以包含非连续数据,但是我使用的模型是share / sphere.obj,它是连续的。该模型不包含法线,就像网格一样。我也验证了范围提取方法,这似乎不是问题所在。同样,我测试的所有内容都表明我的OBJ加载是正确的并且不会产生任何错误,这只会留下我用来显示它的方法。

如果有人可以帮助我,我会非常感激。顺便说一句,我想知道如何给予那些帮助的人。

1 个答案:

答案 0 :(得分:0)

解决:使用(f1-f0)* sizeof(int)而不是nTriangles,除以3,并将sizeof(float)添加到传入的顶点的大小。