I am working on a small game engine and having some troubles when figuring out how to properly map more complex textures to their meshes. I am loading models using the .OBJ format and as far as I can tell, my loader is properly loading all the data into a Vertex list, as the model properly renders, and diffuse shading is applied properly with the normals from the file.
However, when I bind the following texture to its mesh, I get following results.
To bind this texture, I simply did this code:
int width, height;
unsigned char * data = SOIL_load_image("Medieval_House_Diff.png", &width, &height, 0, 0);
GLuint textureID;
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_2D, textureID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glGenerateMipmap(GL_TEXTURE_2D);
Here is my code for reading the OBJ file
while ((line = reader.getLine()) != 0)
{
if (line[0] == 'f' && line[1] == ' ')
{
bool quad = false;
objFP f1 = { 0 };
objFP f2 = { 0 };
objFP f3 = { 0 };
objFP f4 = { 0 };
strtok_s(line, " ", &context);
token = strtok_s(0, " ", &context);
if (sscanf_s(token, "%u/%u/%u", &f1.vPos, &f1.tPos, &f1.nPos) == 3)
{
token = strtok_s(0, " ", &context);
sscanf_s(token, "%u/%u/%u", &f2.vPos, &f2.tPos, &f2.nPos);
token = strtok_s(0, " ", &context);
sscanf_s(token, "%u/%u/%u", &f3.vPos, &f3.tPos, &f3.nPos);
token = strtok_s(0, " ", &context);
if (token)
{
quad = true;
sscanf_s(token, "%u/%u/%u", &f4.vPos, &f4.tPos, &f4.nPos);
}
}
else if (sscanf_s(token, "%u//%u", &f1.vPos, &f1.nPos) == 2)
{
token = strtok_s(0, " ", &context);
sscanf_s(token, "%u//%u", &f2.vPos, &f2.nPos);
token = strtok_s(0, " ", &context);
sscanf_s(token, "%u//%u", &f3.vPos, &f3.nPos);
token = strtok_s(0, " ", &context);
if (token)
{
quad = true;
sscanf_s(token, "%u//%u", &f4.vPos, &f4.nPos);
}
}
else if (sscanf_s(token, "%u/%u", &f1.vPos, &f1.tPos) == 2)
{
token = strtok_s(0, " ", &context);
sscanf_s(token, "%u/%u", &f2.vPos, &f2.tPos);
token = strtok_s(0, " ", &context);
sscanf_s(token, "%u/%u", &f3.vPos, &f3.tPos);
token = strtok_s(0, " ", &context);
if (token)
{
quad = true;
sscanf_s(token, "%u/%u", &f4.vPos, &f4.tPos);
}
}
else
{
f1.vPos = (GLuint)atoi(token);
token = strtok_s(0, " ", &context);
f2.vPos = (GLuint)atoi(token);
token = strtok_s(0, " ", &context);
f3.vPos = (GLuint)atoi(token);
token = strtok_s(0, " ", &context);
if (token)
{
quad = true;
f4.vPos = (GLuint)atoi(token);
}
}
faces[fCount++] = f1;
faces[fCount++] = f2;
faces[fCount++] = f3;
//inds.push_back(f1.vPos - 1);
//inds.push_back(f2.vPos - 1);
//inds.push_back(f3.vPos - 1);
if (quad)
{
faces[fCount++] = f1;
faces[fCount++] = f3;
faces[fCount++] = f4;
//inds.push_back(f1.vPos - 1);
//inds.push_back(f3.vPos - 1);
//inds.push_back(f4.vPos - 1);
}
continue;
}
else if (line[0] == 'v' && line[1] == ' ')
{
strtok_s(line, " ", &context);
vertices[pCount].position.x = strtof(strtok_s(0, " ", &context), 0) * modelScale;
vertices[pCount].position.y = strtof(strtok_s(0, " ", &context), 0) * modelScale;
vertices[pCount++].position.z = strtof(strtok_s(0, " ", &context), 0) * modelScale;
}
else if (line[0] == 'v' && line[1] == 't')
{
strtok_s(line, " ", &context);
tempTextures[tCount].x = strtof(strtok_s(0, " ", &context), 0);
tempTextures[tCount++].y = 1 - strtof(strtok_s(0, " ", &context), 0);
}
else if (line[0] == 'v' && line[1] == 'n')
{
strtok_s(line, " ", &context);
tempNormals[nCount].x = strtof(strtok_s(0, " ", &context), 0);
tempNormals[nCount].y = strtof(strtok_s(0, " ", &context), 0);
tempNormals[nCount++].z = strtof(strtok_s(0, " ", &context), 0);
}
}
reader.release();
bool hasTextures = tCount > 0;
bool hasNormals = nCount > 0;
GLuint * indices = new GLuint[fCount];
for (GLuint i = 0; i < fCount; i++)
{
GLuint index = faces[i].vPos - 1;
indices[i] = index;
if (hasTextures)
vertices[faces[i].vPos - 1].texture = tempTextures[faces[i].tPos - 1];
if (hasNormals)
vertices[index].normal = tempNormals[faces[i].nPos - 1];
}
I have not been able to find a resource online that deals with properly loading a texture such as this, so it would be appreciated if someone with knowledge on such topics could tell me what steps I might be missing to properly map this texture to its mesh.