I have a program I use for test-loading models into OpenGL in C. The code for this is pretty straightforward as far as model loading with Assimp goes (to my understanding):
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);
My loadTexture
function works well for all the other textures I've used, so I doubt that's the problem. And for some of my more basic models I don't have any problems at all. But when I try to load more complex models, like this one:
Quad Shotgun rendered in Blender
The texture coordinates get thrown way off, like this: Quad Shotgun rendered first person
Also, to ensure that it's not an issue with not loading the .mtl
file associated with the .obj
properly, I got rid of everything in the .mtl
except where it defined the texture file so I could still load it into Blender. Same results. I've done my research on Assimp on and I'm sure that it's not a problem with my rendering loop. Please help, I have no idea what else I missed here or what could be going wrong with my program!
A bit of a mistake on my end, while all of the code was correct in loading the model and it's data, I forgot that the flags preset I used for loading the model in aiImportScene
didn't include a flag to flip the UVs. In other words, instead of this:
const struct aiScene* scene = aiImportFile(objfile, aiProcessPreset_TargetRealtime_Fast);
to import the model, I should've been using this:
const struct aiScene* scene = aiImportFile(objfile, aiProcessPreset_TargetRealtime_Fast | aiProcess_FlipUVs);
the key difference being that I added | aiProcess_FlipUVs
to the end of the flags. This has fixed some texturing problems I had with a lot of models that I've either exported from Blender or found on the internet, and it doesn't seem to harm the models that worked fine before. Hope this answer helps if there are others who had a similar problem!