在openGL

时间:2016-01-08 04:46:21

标签: c++ opengl vector wavefront

我是OpenGL的新手,我正在尝试将obj文件加载到我的代码中。我有一个简单的动画立方体的代码。当我按如下方式声明顶点和索引时,它可以正常工作:

GLfloat cube_vertices[] = {
// front
    -1.0, -1.0, 1.0,
    1.0, -1.0, 1.0,
    1.0, 1.0, 1.0,
    -1.0, 1.0, 1.0,
    // back
    -1.0, -1.0, -1.0,
    1.0, -1.0, -1.0,
    1.0, 1.0, -1.0,
    -1.0, 1.0, -1.0,
};
GLushort cube_elements[] = {
    // front
    0, 1, 2,
    2, 3, 0,
    // top
    1, 5, 6,
    6, 2, 1,
    // back
    7, 6, 5,
    5, 4, 7,
    // bottom
    4, 0, 3,
    3, 7, 4,
    // left
    4, 5, 1,
    1, 0, 4,
    // right
    3, 2, 6,
    6, 7, 3,
};

但是,当我尝试从文件中获取相似的数字时,程序运行时没有错误,但在窗口中没有显示任何内容。这是我加载obj文件的代码:

vector<GLfloat> vertices;
vector<GLushort> elements;

ifstream in("cube.obj", ios::in);
if (!in)
{
    cerr << "Cannot open " << "sample.obj" << endl; exit(1);
}

string line;
while (getline(in, line))
{
    if (line.substr(0, 2) == "v ")
    {
        istringstream s(line.substr(2));
        GLfloat v;
        s >> v; vertices.push_back(v);
        s >> v; vertices.push_back(v);
        s >> v; vertices.push_back(v);

    }
    else if (line.substr(0, 2) == "f ")
    {
        istringstream s(line.substr(2));
        GLushort a, b, c;
        s >> a; s >> b; s >> c;
        elements.push_back(a); elements.push_back(b); elements.push_back(c);
    }
}

cube.obj文件保存如下:

o cube
v -1.0 -1.0 1.0
v 1.0 -1.0 1.0
v 1.0 1.0 1.0
v -1.0 1.0 1.0
v -1.0 -1.0 -1.0
v 1.0 -1.0 -1.0
v 1.0 1.0 -1.0
v -1.0 1.0 -1.0
f 0 1 2
f 2 3 0
f 1 5 6
f 6 2 1
f 7 6 5
f 5 4 7
f 4 0 3
f 3 7 4
f 4 5 1
f 1 0 4
f 3 2 6
f 6 7 3

我只是在输出中得到一个空白窗口。你知道装载机为什么不起作用吗?

我上传数据

glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), &vertices, GL_STATIC_DRAW);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), &elements, GL_STATIC_DRAW);

如果我未在&vertices之前放置elements运算符,则会出现“无适当转换”的编译错误。

2 个答案:

答案 0 :(得分:2)

glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), &vertices, GL_STATIC_DRAW);

glBufferData期望原始数据而不是直接向量,也应该正确地给出这些数据的大小。你在这里做的是传递vector本身的大小而不是它包含的数据。

vector是一个数据结构,一个容器,其元数据类似于指向它将要保存的数据的指针,以及一个变量来保存它所持有的元素的数量。当你执行sizeof(vector)时,它总是会返回一个常数,而不管它所包含的元素数量是多少;这个大小是sizeof(pointer-to-data) + sizeof(variable-holding-count)。这些数据不是您想要的。

此外,当您传递&vertices时,您传递的是矢量本身的地址,而不是它包含的数据的地址。 vector::data()给出了其中包含的数据的地址。

而是这样做:

glBufferData(GL_ARRAY_BUFFER,
             vertices.size() * sizeof(GLfloat),
             vertices.data(),
             GL_STATIC_DRAW);

应该这样做。元素数组缓冲区也是如此。

glBufferData(GL_ELEMENT_ARRAY_BUFFER,
             elements.size() * sizeof(GLushort),
             elements.data(),
             GL_STATIC_DRAW);

vector::size()给出了它包含的元素的数量,即一个元素的大小给出了所包含数据的正确大小。

除了

line.substr(0, 2) == "v "
line.substr(0, 2) == "f "

这会不必要地创建两个子字符串,而是可以执行此操作来检查相同的内容

line[0] == 'v'
line[0] == 'f'

答案 1 :(得分:1)

您发布的代码在顶点和面上加载得很好,因此您需要发布渲染代码以获得特定答案。

根据您发布的内容,我有一些建议:

  • 您在指定多维数据集时使用了cube_vertices和cube_elements,但在从文件加载时使用了不同的变量。您是否尝试从程序中的空数组进行渲染?