gpt4 book ai didi

c++ - obj 加载器无法在 C++ OpenGL 中正确显示

转载 作者:搜寻专家 更新时间:2023-10-31 01:43:16 28 4
gpt4 key购买 nike

我的 wavefront .obj 加载器有问题,它没有显示我想要它显示的内容。我希望它显示一个立方体,但我一直得到这个: enter image description here

这是我的obj文件

# cube.obj
#

g cube

v 0.0 0.0 0.0
v 0.0 0.0 1.0
v 0.0 1.0 0.0
v 0.0 1.0 1.0
v 1.0 0.0 0.0
v 1.0 0.0 1.0
v 1.0 1.0 0.0
v 1.0 1.0 1.0

vn 0.0 0.0 1.0
vn 0.0 0.0 -1.0
vn 0.0 1.0 0.0
vn 0.0 -1.0 0.0
vn 1.0 0.0 0.0
vn -1.0 0.0 0.0

f 1//2 7//2 5//2
f 1//2 3//2 7//2
f 1//6 4//6 3//6
f 1//6 2//6 4//6
f 3//3 8//3 7//3
f 3//3 4//3 8//3
f 5//5 7//5 8//5
f 5//5 8//5 6//5
f 1//4 5//4 6//4
f 1//4 6//4 2//4
f 2//1 6//1 8//1
f 2//1 8//1 4//1

我在我的代码中添加了部分以查​​看是否所有内容都正确存储,顶点和法线是否存储为 GLfloats

显示:

输入:

enter image description here

这是我的绘制函数:我不太确定 glDrawArrays 中的最后一个参数,它是硬编码的,因为我不太确定索引的数量。

void Draw(void)
{
glPushMatrix();
glClearColor(0,0,0,1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();

glRotatef( rotate_x, 1.0, 0.0, 0.0 );
glRotatef( rotate_y, 0.0, 1.0, 0.0 );

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);

glNormalPointer(GL_FLOAT, 0, normals);
glVertexPointer(3, GL_FLOAT,0, vertices);

glDrawArrays(GL_TRIANGLES, 0, (14));

glTranslatef(0, 0, -3);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);


glFlush();
glutSwapBuffers();
glPopMatrix();
}

这也是我的主要内容:

int main(int argc,char** argv)
{
glutInit(&argc, argv);

glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(500, 500);

glutCreateWindow("Object Loader!");

glEnable(GL_DEPTH_TEST);
//glEnable(GL_LIGHTING);
//glEnable(GL_LIGHT0);

GLfloat posLight0[] = {0.0f, 0.0f, -1.0f, 0.0f};
GLfloat lightColor[] = {1.0f, 1.0f, 1.0f, 1.0f};

glLightfv(GL_LIGHT0, GL_POSITION, posLight0);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor);

setUpArrays();

glutDisplayFunc(Draw);
glutSpecialFunc(specialKeys);
glutReshapeFunc(reshape);

glutMainLoop();
return 0;
}

最后一件事是不允许我使用 glDrawElements 或 glBegin() 直接模式。

以下是我的程序的更多内容,如果有帮助的话:开头的全局变量设置

GLfloat* vertices;
GLfloat* normals;
GLint* faces;
int amountOfFaces;
double rotate_y=0;
double rotate_x=0;
Loader* loader = new Loader();

为顶点、法线和索引设置数组:

void setUpArrays()
{
loader->loadObject("cube.obj");


vector<GLfloat> temp = loader->getVerticies();
vertices = new GLfloat[temp.size()];
int tempSize = 0;
cout << "vectors: ";
for(vector<GLfloat>::const_iterator i = temp.begin(); i != temp.end(); ++i)
{
vertices[tempSize] = *i;
cout << vertices[tempSize] << ", ";
tempSize++;
}
cout << endl;
vector<GLfloat> tempNormal = loader->getNormals();
normals = new GLfloat[tempNormal.size()];
tempSize = 0;
cout << "normals: ";
for(vector<GLfloat>::const_iterator i = tempNormal.begin(); i != tempNormal.end(); ++i)
{
normals[tempSize] = *i;
cout << normals[tempSize] << ", ";
tempSize++;
}
amountOfFaces = tempSize;
cout << endl;

vector<GLint> tempIndices = loader->getFaces();
faces = new GLint[tempIndices.size()];
tempSize = 0;
cout << "Indices: ";
for(vector<GLint>::const_iterator i = tempIndices.begin(); i != tempIndices.end(); ++i)
{
faces[tempSize] = *i;
cout << faces[tempSize] << ", ";
tempSize++;
}
cout << endl;

amountOfFaces += tempSize;
}

最佳答案

我对为什么 OBJ 格式给出的顶点属性索引从 1 而不是 0 开始感到困惑。即f 1//2 指的是第一个顶点和第二个法线。您的调试输出没有在索引中显示零,所以我猜加载程序没有考虑到这一点。

A valid vertex index starts from 1 and matches the corresponding vertex elements of a previously defined vertex list. Each face can contain three or more vertices. [wikipedia]

希望修复像这样简单:faces[tempSize] = *i - 1;

[编辑]
您的绘图调用指定了 14 个顶点,但您有 12 个三角形,因此应该绘制 36 个。amountOfFaces 听起来应该是 tempIndices.size()/3

您的 vector 应该是引用以避免复制,并且使用单个 memcpy 填充 faces 等会更快。例如:memcpy(faces, &tempIndices.front(), sizeof(GLint) * tempIndices.size())

[编辑]
哦,对,当然。现在我为没有注意到而感到愚蠢。 Faces 索引顶点,因此可以重复使用它们(节省内存和额外处理)。而不是 glDrawArrays 你想要这个:

glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, faces); //replate 36 for things you draw that aren't cubes

如果您想使用 glDrawArrays,您必须重新排列顶点数组,以便每个顶点都按照 faces 给出的顺序出现,包括所有重复项。例如,您的新位置数组将是 [0,0,0, 1,1,0 1,0,0 ...] 是构成第一个三角形的 vector 0,6,4。 std::vector 使这种重新排列易于编码。

最后一件事。法线数组没有位置数组那么大,但 OpenGL 不支持混合索引。所以你必须复制一些法线,这样每个顶点都有一个位置和法线。

关于c++ - obj 加载器无法在 C++ OpenGL 中正确显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25507794/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com