对象模型加载纹理坐标和顶点位置没有正确加载
obj model loading texture coords and vertex position not loaded correctly
我正在加载一个3d .obj模型到我的游戏中,然而这是它现在的样子:
绝对不是它应该看起来的样子。我想可能是我连接索引的方式是错误的,但我就是找不到问题
这是我的代码:
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 %fn", &vertex.x, &vertex.y, &vertex.z);
positionVec.push_back(vertex);
}
else if (strcmp(lineHeader, "vt") == 0) {
glm::vec2 uv;
fscanf(file, "%f %fn", &uv.x, &uv.y);
texCoordVec.push_back(uv);
}
else if (strcmp(lineHeader, "vn") == 0) {
glm::vec3 normal;
fscanf(file, "%f %f %fn", &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/%dn", &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的。你在填充向量vertexPositions
等时考虑这个。但之后就不用这些向量了。直接使用OBJ中的索引作为索引缓冲区是行不通的。你需要减去1。正如genpfault在评论中提到的,索引甚至可以是负的相对引用。
OBJ中的面顶点可以引用不同的位置和法线id(以及纹理坐标id)。这是你不能在OpenGL中表示的东西,你需要复制一些数据。因此,这种方法只在引用的id都相同的情况下才有效。
相关文章:
- std::原子加载和存储都需要吗
- 如何加载(或映射)文件部分的最大大小,但适合在Windows上的RAM
- C++ 雷神库 - 使用资源加载器类时出现问题(不命名类型)
- 为什么加载SDF会导致Mobilizer创建闭环错误
- C++atioglxx.pdb未加载错误glBufferData OpenGL
- 如何使用tinyxml2从XML加载父实体和子实体
- 如何在C++中使用pybind11加载一个pickle python列表
- 系统.将数组移交给c#中动态加载的c++DLL时发生AccessViolationException
- 当我尝试加载内核模块时,如何修复C++中的这个 malloc() 错误?
- 树莓上的 Libtorch 无法加载 pt 文件,但在 ubuntu 上工作
- 在动态加载的位置无关的可执行文件中分离错误
- SFML鼠标位置和碰撞从文件加载
- DirectX11 网格加载 - 由于纹理而出错(使用 SDKmesh.h)?访问违规读取位置0x00000000
- 如何在__m128i的特定位置加载字节
- CPU 缓存是否也从以前的内存位置加载信息
- 制作包含地图或场景信息的文件,例如要加载的资源、对象、位置、事件
- 如何判断共享库在进程地址空间中的加载位置
- C++Qt QGraphicsView:重新加载后记住滚动条的位置
- 对象模型加载纹理坐标和顶点位置没有正确加载
- visual studio 2010 -查找dll在c++程序(MFC)中的加载位置