我是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
运算符,则会出现“无适当转换”的编译错误。
答案 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)
您发布的代码在顶点和面上加载得很好,因此您需要发布渲染代码以获得特定答案。
根据您发布的内容,我有一些建议: