gpt4 book ai didi

c++ - obj 模型加载纹理坐标和顶点位置未正确加载

转载 作者:行者123 更新时间:2023-11-30 16:55:37 24 4
gpt4 key购买 nike

我正在将 3d .obj 模型加载到我的游戏中,但这就是现在的样子:3d model

这绝对不是它想象的那样。我想也许是我连接索引的方式是错误的,但我就是找不到问题

这是我的代码:

 char lineHeader[128];
FILE * file = fopen(fileName, "r");

if (file == NULL) {
printf("Impossible to open the file !\n");
}

vector <vec3> positionVec;
vector <vec2> texCoordVec;
vector <vec3> normalVec;
vector <GLuint> vertexIndices;
vector <GLuint> uvIndices;
vector <GLuint> normalIndices;

while (true) {
char lineHeader[128];
int res = fscanf(file, "%s", lineHeader);

if (res == EOF) {
break;
}

if (strcmp(lineHeader, "v") == 0) {
glm::vec3 vertex;
fscanf(file, "%f %f %f\n", &vertex.x, &vertex.y, &vertex.z);
positionVec.push_back(vertex);
}
else if (strcmp(lineHeader, "vt") == 0) {
glm::vec2 uv;
fscanf(file, "%f %f\n", &uv.x, &uv.y);
texCoordVec.push_back(uv);
}
else if (strcmp(lineHeader, "vn") == 0) {
glm::vec3 normal;
fscanf(file, "%f %f %f\n", &normal.x, &normal.y, &normal.z);
normalVec.push_back(normal);
}
else if (strcmp(lineHeader, "f") == 0) {
int vertexIndex1, vertexIndex2, vertexIndex3, uvIndex1, uvIndex2, uvIndex3, normalIndex1, normalIndex2, normalIndex3;
fscanf(file, "%d/%d/%d %d/%d/%d %d/%d/%d\n", &vertexIndex1, &uvIndex1, &normalIndex1, &vertexIndex2, &uvIndex2, &normalIndex2, &vertexIndex3, &uvIndex3, &normalIndex3);
vertexIndices.push_back(vertexIndex1);
vertexIndices.push_back(vertexIndex2);
vertexIndices.push_back(vertexIndex3);
uvIndices.push_back(uvIndex1);
uvIndices.push_back(uvIndex2);
uvIndices.push_back(uvIndex3);
normalIndices.push_back(normalIndex1);
normalIndices.push_back(normalIndex2);
normalIndices.push_back(normalIndex3);
}
}

vector <vec3> vertexPositions;
vector <vec2> textureCoords;
vector <vec3> normals;

for (unsigned int i = 0; i < vertexIndices.size(); i++) {
vertexIndices[i] = vertexIndices[i] - 1;
}

for (unsigned int i = 0; i < uvIndices.size(); i++) {
unsigned int index = uvIndices[i];
vec2 uv = texCoordVec[index - 1];
textureCoords.push_back(uv);
}

for (unsigned int i = 0; i < normalIndices.size(); i++) {
unsigned int index = normalIndices[i];
vec3 normal = normalVec[index - 1];
normals.push_back(normal);
}

GLuint modelVertecesBuffer;
glGenBuffers(1, &modelVertecesBuffer);
glBindBuffer(GL_ARRAY_BUFFER, modelVertecesBuffer);
glBufferData(GL_ARRAY_BUFFER, positionVec.size() * sizeof(glm::vec3), &positionVec[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

GLuint modelTextureCoordBuffer;
glGenBuffers(1, &modelTextureCoordBuffer);
glBindBuffer(GL_ARRAY_BUFFER, modelTextureCoordBuffer);
glBufferData(GL_ARRAY_BUFFER, texCoordVec.size() * sizeof(vec2), &texCoordVec[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, 0);

GLuint modelNormalBuffer;
glGenBuffers(1, &modelNormalBuffer);
glBindBuffer(GL_ARRAY_BUFFER, modelNormalBuffer);
glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(vec3), &normals[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);

GLuint positionIndicesBuffer;
glGenBuffers(1, &positionIndicesBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, positionIndicesBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, vertexIndices.size() * sizeof(int), &vertexIndices[0], GL_STATIC_DRAW);

最佳答案

有几件事:

OBJ 模型中的索引是从 1 开始的。您在填充 vector vertexPositions 等时考虑这一点。但此后您不会使用这些 vector 。直接使用 OBJ 中的索引作为索引缓冲区是行不通的。你必须减去一。正如 genpfault 在评论中提到的,相对引用的索引甚至可以为负。

OBJ 中的面顶点可能引用不同的位置和法线 id(以及纹理坐标 id)。这是您无法在 OpenGL 中表示的内容,您需要复制一些数据。因此,只有引用的 id 全部相同时,这种方法才有效。

关于c++ - obj 模型加载纹理坐标和顶点位置未正确加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40238523/

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