#include "Obj_loader.h"
Obj_loader::Obj_loader()
{
}
Obj_loader::~Obj_loader()
{
}
Static_Mesh* Obj_loader::Load(IDirect3DDevice9* Dx9Device, std::string dir)
{
//get path, ie c:/files/type/hj.obj ------> c:/files/type/
std::string::size_type pos = dir.find_last_of('\\');
std::string path;
if(pos != std::string::npos)
path = dir.substr(0, pos + 1);
else
{
MessageBox(0, "Cant referenece file path", "Error !", 0);
}
struct PTNS
{
int Pos;
int Tex;
int Norm;
int Subset;
};
Static_Mesh* pMesh = new Static_Mesh();
std::vector<D3DXVECTOR3> Vertices;
std::vector<D3DXVECTOR2> TexCoor;
std::vector<D3DXVECTOR3> Normals;
std::vector<PTNS> Mesh;
int cSubset = -1;
std::map < std::string, Material > Materials;
std::ifstream objFile(dir.c_str());
if(!objFile.is_open())
{
char buffer[50];
sprintf_s(buffer, "Error opening %s", dir.c_str());
MessageBox(NULL, buffer, "Error", NULL);
}
std::string fullLine;
std::string firstword;
while(objFile.is_open())
{
getline(objFile, fullLine);
if(objFile.eof())
break;
std::stringstream line(fullLine);
line >> firstword;
if (firstword == "#")
{
//comment code
}
if (firstword == "mtllib")
{
line >> firstword;
//remove './' and add filldirectory
std::string str = firstword.substr(2, firstword.size() -1 );
std::string path2 = path + str;
ReadMtrl(&Materials, path2.c_str(), path);
}
if (firstword == "usemtl")
{
line >> firstword;
pMesh->Materials.push_back(Materials.find(firstword)->second);
++cSubset;
}
if (firstword == "v")
{
//vertex code
static D3DXVECTOR3 v;
line >> v.x >> v.y >> v.z;
Vertices.push_back(v);
}
if (firstword == "vt")
{
//texture code
D3DXVECTOR2 t;
line >> t.x >> t.y;
TexCoor.push_back(t);
}
if (firstword == "vn")
{
//normal code
static D3DXVECTOR3 n;
line >> n.x >> n.y >> n.z;
Normals.push_back(n);
}
if (firstword == "f" )
{
//face code
for(int i = 0; i < 3; ++i)
{
static PTNS temp;
line >> temp.Pos;
line.ignore(256, '/');
line >> temp.Tex;
line.ignore(256, '/');
line >> temp.Norm;
temp.Subset = cSubset;
Mesh.push_back(temp);
}
}
if (firstword == "g")
{
//nothing here yet
}
if (firstword == "g")
{
//nothing here yet
}
}
//D3DVERTEXELEMENT9 VertexPNTElements[] =
//{
// {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
// {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
// {0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
// D3DDECL_END()
//};
//Dx9Device->CreateVertexDeclaration(VertexPNTElements, &VertexPNT::Decl);
assert(Mesh.size() < 65534);
D3DVERTEXELEMENT9 decl[MAXD3DDECLLENGTH];
UINT numElements;
VertexPNT::Decl->GetDeclaration( decl, &numElements);
D3DXCreateMesh( Mesh.size() / 3, //Faces
Mesh.size(), D3DXMESH_MANAGED, //Vertices
decl, //V declaration
Dx9Device, &pMesh->Mesh
);
//vertex buffer
//==============================================================================================================
VertexPNT* v = 0;
pMesh->Mesh->LockVertexBuffer(0, (void**)&v);
for(int i = 0; i < (int)pMesh->Mesh->GetNumVertices(); i++)
{
// Fill in the front face vertex data.
v = VertexPNT(
Vertices [(Mesh.Pos) -1 ],
Normals [(Mesh.Norm) -1],
TexCoor [(Mesh.Tex) -1]
);
}
VertexPNT y = v[Mesh.size()-1];
pMesh->Mesh->UnlockVertexBuffer();
//Index buffer
//==============================================================================================================
WORD* in = 0;
pMesh->Mesh->LockIndexBuffer(0, (void**)&in);
for(int k = 0; k < (int)pMesh->Mesh->GetNumVertices(); k++)
{
in[k] = k;
}
pMesh->Mesh->UnlockIndexBuffer();
//attribute buffer
//==============================================================================================================
DWORD* at = 0;
pMesh->Mesh->LockAttributeBuffer(0, &at);
for(int k = 0; k < (int)pMesh->Mesh->GetNumFaces(); ++k)
{
at[k] = 0;
}
pMesh->Mesh->UnlockAttributeBuffer();
return pMesh;
}
void Obj_loader::ReadMtrl(std::map < std::string, Material > * map, const char *file, std::string dir)
{
D3DMATERIAL9 tMat;
std::ifstream mFile(file);
if(!mFile.is_open())
{
char buffer[50];
sprintf_s(buffer, "Error opening %s", file);
MessageBox(NULL, buffer, "Error", NULL);
return;
}
std::string fullLine;
std::string firstword;
std::string CurrentMaterial;
while(mFile)
{
getline(mFile, fullLine);
if(mFile.eof())
break;
std::stringstream line(fullLine);
line >> firstword;
if(firstword == "#")
{
}
if(firstword == "newmtl")
{
//add a new material
line >> CurrentMaterial;
(*map)[CurrentMaterial];
}
if(firstword == "Ka") //ambient colour
{
//dont bother, ambient == diffuse
}
if(firstword == "Kd") //diffuse colour
{
line >> (*map)[CurrentMaterial].Diffuse.r
>> (*map)[CurrentMaterial].Diffuse.g
>> (*map)[CurrentMaterial].Diffuse.b;
(*map)[CurrentMaterial].Diffuse.a = 1.0f;
(*map)[CurrentMaterial].Ambient = (*map)[CurrentMaterial].Diffuse;
}
if(firstword == "Ks") //specular colour
{
line >> (*map)[CurrentMaterial].Specular.r
>> (*map)[CurrentMaterial].Specular.g
>> (*map)[CurrentMaterial].Specular.b;
(*map)[CurrentMaterial].Specular.a = 1.0f;
}
if(firstword == "d") //opacity
{
line >> (*map)[CurrentMaterial].Diffuse.a;
}
if(firstword == "Ns") //specular power
{
line >> (*map)[CurrentMaterial].Power;
}
if(firstword == "illum") //emmisive???
{
//meh
}
if(firstword == "map_Kd") //diffuse texture
{
std::string name;
line >> name;
(*map)[CurrentMaterial].TexDiffuse = Texture_Mgr::Load(dir + name);
}
}
mFile.close();
}
About ready to rip my hair out over these Texture coordinates
Hey Guys,
Ive been working on this problem all night, for some reason, on a few objects, the texture coordinates get messed up. As you can see from the pics below, all the texture coordinates are correct, apart from the spanner. When i say correct, i mean to what i set them to in 3ds max, with the shapes just having the faces mapped to each texture.
Below is what its suppose to look like
Below is what i get in my app
The files are being read from an obj reader i wrote, which seems to have a bug with the texture coordinates, but for the life of me i cant figure it out.
The code at the moment is very unoptimized, and i haven't gone into creating index's or anything yet as i wanted to get this working first
First it reads the mtrl file
Then it reads the verts, normals and textures into separate vectors
Then it reads the faces, creating a mesh vector
Then it pumps that into a DX mesh
can you see anything wrong?
I'd suggest that you first compare the texture coordinates you've created in the vertex buffer to what you have in MAX. See if there's a difference, and try to track its cause. If there's no difference, either you're misinterpreting the MAX data in the first place, or there's another bug in the drawing.
Just a thought, but when I export from MAX i have to negate the "y" or "v" texture coordinate.
when i load it in I basically go textureCoord.y *= -1;
I'm using openGL though not directX
when i load it in I basically go textureCoord.y *= -1;
I'm using openGL though not directX
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement