About ready to rip my hair out over these Texture coordinates

Started by
2 comments, last by wforl 15 years, 5 months ago
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 Photobucket Below is what i get in my app Photobucket 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

#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();
}

can you see anything wrong?
Advertisement
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
ah yes, how silly of me, i was thinking in terms of Max UV, and forgot that Directx had a different layout

thanks for reminding me, what a silly mistake

dx
0,0--------------1,0
i
i
i
i
i
i
i
0,1--------------1,1


max
0,1--------------1,1
i
i
i
i
i
i
i
0,0--------------1,0




This topic is closed to new replies.

Advertisement