模型纹理坐标opengl的问题
Problems with model texture coords opengl
我有一个程序用于在 C 中测试将模型加载到 OpenGL 中。就使用 Assimp 加载模型而言(据我所知),此代码非常简单:
const struct aiScene* scene = aiImportFile(objfile, aiProcessPreset_TargetRealtime_Fast);
unsigned int vbo, ibo, tex;
if(scene == NULL)
{
fprintf(stderr, "Could not load file '%s'\n", objfile);
return 1;
}
int count = 0, size = 0;
int i, j, k;
for(i = 0; i < scene->mNumMeshes; i ++)
size += (3 * scene->mMeshes[i]->mNumFaces);
Vertex* vertices = (Vertex*)malloc(size * sizeof(Vertex));
int* indices = (int*)malloc(size * sizeof(int));
for(i = 0; i < scene->mNumMeshes; i ++)
{
struct aiMesh* mesh = scene->mMeshes[i];
int meshFaces = mesh->mNumFaces;
for(j = 0; j < meshFaces; j ++)
{
struct aiFace* face = &(mesh->mFaces[j]);
for(k = 0; k < face->mNumIndices; k ++)
{
int index = face->mIndices[k];
struct aiVector3D pos = mesh->mVertices[index];
struct aiVector3D uv = mesh->mTextureCoords[0][index];
struct aiVector3D normal = {.x=1.0f,.y=1.0f,.z=1.0f};
if(mesh->mNormals != NULL)
normal = mesh->mNormals[index];
Vertex _vertex = {.x=pos.x * scale,
.y=pos.y * scale,
.z=pos.z * scale,
.u=uv.x, .v=uv.y,
.nx=normal.x * scale,
.ny=normal.y * scale,
.nz=normal.z * scale};
vertices[count] = _vertex;
indices[count] = count;
count ++;
}
}
}
aiReleaseImport(scene);
tex = loadTexture(texfile);
if(tex == 0)
{
fprintf(stderr, "Could not load file '%s'\n", texfile);
return 1;
}
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, size * sizeof(Vertex), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glGenBuffers(1, &ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, size * sizeof(int), indices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
我的 loadTexture
函数适用于我使用过的所有其他纹理,所以我怀疑这就是问题所在。对于我的一些更基本的模型,我根本没有任何问题。但是当我尝试加载更复杂的模型时,比如这个:
Quad Shotgun rendered in Blender
纹理坐标被抛得很远,像这样:Quad Shotgun rendered first person
此外,为了确保不正确加载与 .obj
关联的 .mtl
文件不是问题,我删除了 .mtl
中的所有内容,除了它定义的地方纹理文件,这样我仍然可以将它加载到 Blender 中。相同的结果。我已经完成了对 Assimp 的研究,我确信这不是我的渲染循环的问题。请帮忙,我不知道我在这里还遗漏了什么或者我的程序可能出了什么问题!
我有点失误,虽然所有代码在加载模型及其数据时都是正确的,但我忘记了我在 aiImportScene
中用于加载模型的标志预设没有包括一个标志来翻转 UV。换句话说,而不是这个:
const struct aiScene* scene = aiImportFile(objfile, aiProcessPreset_TargetRealtime_Fast);
要导入模型,我应该一直使用这个:
const struct aiScene* scene = aiImportFile(objfile, aiProcessPreset_TargetRealtime_Fast | aiProcess_FlipUVs);
主要区别在于我在标志的末尾添加了 | aiProcess_FlipUVs
。这解决了我从 Blender 导出或在 Internet 上找到的许多模型遇到的一些纹理问题,并且它似乎不会损害之前运行良好的模型。希望这个回答对其他遇到类似问题的人有所帮助!
我有一个程序用于在 C 中测试将模型加载到 OpenGL 中。就使用 Assimp 加载模型而言(据我所知),此代码非常简单:
const struct aiScene* scene = aiImportFile(objfile, aiProcessPreset_TargetRealtime_Fast);
unsigned int vbo, ibo, tex;
if(scene == NULL)
{
fprintf(stderr, "Could not load file '%s'\n", objfile);
return 1;
}
int count = 0, size = 0;
int i, j, k;
for(i = 0; i < scene->mNumMeshes; i ++)
size += (3 * scene->mMeshes[i]->mNumFaces);
Vertex* vertices = (Vertex*)malloc(size * sizeof(Vertex));
int* indices = (int*)malloc(size * sizeof(int));
for(i = 0; i < scene->mNumMeshes; i ++)
{
struct aiMesh* mesh = scene->mMeshes[i];
int meshFaces = mesh->mNumFaces;
for(j = 0; j < meshFaces; j ++)
{
struct aiFace* face = &(mesh->mFaces[j]);
for(k = 0; k < face->mNumIndices; k ++)
{
int index = face->mIndices[k];
struct aiVector3D pos = mesh->mVertices[index];
struct aiVector3D uv = mesh->mTextureCoords[0][index];
struct aiVector3D normal = {.x=1.0f,.y=1.0f,.z=1.0f};
if(mesh->mNormals != NULL)
normal = mesh->mNormals[index];
Vertex _vertex = {.x=pos.x * scale,
.y=pos.y * scale,
.z=pos.z * scale,
.u=uv.x, .v=uv.y,
.nx=normal.x * scale,
.ny=normal.y * scale,
.nz=normal.z * scale};
vertices[count] = _vertex;
indices[count] = count;
count ++;
}
}
}
aiReleaseImport(scene);
tex = loadTexture(texfile);
if(tex == 0)
{
fprintf(stderr, "Could not load file '%s'\n", texfile);
return 1;
}
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, size * sizeof(Vertex), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glGenBuffers(1, &ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, size * sizeof(int), indices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
我的 loadTexture
函数适用于我使用过的所有其他纹理,所以我怀疑这就是问题所在。对于我的一些更基本的模型,我根本没有任何问题。但是当我尝试加载更复杂的模型时,比如这个:
Quad Shotgun rendered in Blender
纹理坐标被抛得很远,像这样:Quad Shotgun rendered first person
此外,为了确保不正确加载与 .obj
关联的 .mtl
文件不是问题,我删除了 .mtl
中的所有内容,除了它定义的地方纹理文件,这样我仍然可以将它加载到 Blender 中。相同的结果。我已经完成了对 Assimp 的研究,我确信这不是我的渲染循环的问题。请帮忙,我不知道我在这里还遗漏了什么或者我的程序可能出了什么问题!
我有点失误,虽然所有代码在加载模型及其数据时都是正确的,但我忘记了我在 aiImportScene
中用于加载模型的标志预设没有包括一个标志来翻转 UV。换句话说,而不是这个:
const struct aiScene* scene = aiImportFile(objfile, aiProcessPreset_TargetRealtime_Fast);
要导入模型,我应该一直使用这个:
const struct aiScene* scene = aiImportFile(objfile, aiProcessPreset_TargetRealtime_Fast | aiProcess_FlipUVs);
主要区别在于我在标志的末尾添加了 | aiProcess_FlipUVs
。这解决了我从 Blender 导出或在 Internet 上找到的许多模型遇到的一些纹理问题,并且它似乎不会损害之前运行良好的模型。希望这个回答对其他遇到类似问题的人有所帮助!