Exemplo n.º 1
0
// doesn't parse any properties yet
// but it reads the texture files
void readMtlFile(std::vector <Material> *textureFiles, LPCTSTR mtlFile, WCHAR *folder)
{
	std::wifstream fileStream;
	std::wstring line;

	fileStream.open(mtlFile);
	bool isOpen = fileStream.is_open();

	if (!isOpen)
		throw std::logic_error("mtl file not found");

	while (std::getline(fileStream, line))
	{
		line = TrimStart(line);

		// material
		if (line.compare(0, 7, L"newmtl ") == 0)
		{
			Material material;

			WCHAR first[20];

			WCHAR oldStyleStr[200];
			wcscpy(oldStyleStr, line.c_str());
			swscanf(oldStyleStr, L"%7s%s", first, &material.materialName);
			
			textureFiles->push_back(material);
			continue;
		}

		// filename of texture
		if (line.compare(0, 7, L"map_Kd ") == 0)
		{
			WCHAR first[10], fileName[200];

			WCHAR oldStyleStr[200];
			wcscpy(oldStyleStr, line.c_str());
			swscanf(oldStyleStr, L"%7s%s", first, &fileName);

			// construct the full filepath
			WCHAR fullTextureFilePath[200];
			wcscpy(fullTextureFilePath, folder);
			wcsncat(fullTextureFilePath, fileName, 200);

			textureFiles->back().hasTexture = true;
			wcscpy(textureFiles->back().textureFilePath, fullTextureFilePath);
			continue;
		}
	}
}
String String::Trim(String remove) const
{
    String noStart = TrimStart(remove);
    return noStart.TrimEnd(remove);
}
Exemplo n.º 3
0
void ObjMeshInfo::loadMesh(ID3D11Device* pd3dDevice)
{
	if (!fromFile)
	{
		specialLoad(pd3dDevice);
		return;
	}

	std::wifstream          fileStream;
	std::wstring            line;
	std::vector <XMFLOAT3> vectorVertices(0);
	std::vector <XMFLOAT3> vectorNormals(0);
	std::vector <XMFLOAT2> vectorUVs(0);
	std::vector <Index>    vectorIndices(0);
	std::vector <Material> vectorTextureFiles(0);

	fileStream.open(file);
	bool isOpen = fileStream.is_open();		//debugging only.

	// convert LPCTSTR to WCHAR
	WCHAR wfile[200];
	wcscpy(wfile, file);

	// get the folder so we can prepend it to filenames later
	WCHAR folder[200];
	getFolder(folder, wfile);


	bool newMaterial = false;
	WCHAR materialName[200];

	// now we can start to read the obj file!
	while (std::getline(fileStream, line))
	{
		line = TrimStart(line);

		// materials
		if (line.compare(0, 7, L"usemtl ") == 0)
		{
			WCHAR first[20];
			// I'm actually treating a 'material' as a submesh. not sure if this is correct

			WCHAR oldStyleStr[200];
			wcscpy(oldStyleStr, line.c_str());
			swscanf(oldStyleStr, L"%7s%s", first, materialName);

			// we want the next index to have the newMaterial flag
			newMaterial = true;

			continue;
		}

		//******************************************************************//
		// If true, we have found a vertex.  Read it in as a 2 character	//
		// string, followed by 3 decimal numbers.	Suprisingly the C++		//
		// string has no split() method.   I am using really old stuff,		//
		// fscanf.  There  must be a better way, use regular expressions?	//
		//******************************************************************//
		if (line.compare(0, 2, L"v ") == 0)  //"v space"
		{
			WCHAR first[10];
			float x, y, z;

			WCHAR oldStyleStr[200];
			wcscpy(oldStyleStr, line.c_str());
			swscanf(oldStyleStr, L"%2s%f%f%f", first, &x, &y, &z);

			XMFLOAT3 v = XMFLOAT3(x, y, z);
			vectorVertices.push_back(v);
			continue;
		}

		// normals
		if (line.compare(0, 3, L"vn ") == 0)  //"vn space"
		{
			WCHAR first[10];
			float x, y, z;

			WCHAR oldStyleStr[200];
			wcscpy(oldStyleStr, line.c_str());
			swscanf(oldStyleStr, L"%3s%f%f%f", first, &x, &y, &z);

			XMFLOAT3 v = XMFLOAT3(x, y, z);
			vectorNormals.push_back(v);
			continue;
		}

		// texture coordinates
		if (line.compare(0, 3, L"vt ") == 0)  //"vt space"
		{
			WCHAR first[10];
			float u, v;

			WCHAR oldStyleStr[200];
			wcscpy(oldStyleStr, line.c_str());
			swscanf(oldStyleStr, L"%3s%f%f", first, &u, &v);

			XMFLOAT2 vert = XMFLOAT2(u, v); 
			vectorUVs.push_back(vert);
			continue;
		}

		//******************************************************************//
		// If true, we have found a face.   Read it in as a 2 character		//
		// string, followed by 3 decimal numbers.	Suprisingly the C++		//
		// string has no split() method.   I am using really old stuff,		//
		// fscanf.  There must be a better way, use regular expressions?	//
		//																	//
		// It assumes the line is in the format								//
		// f v1/vt1/vn1 v2/vt2/vn2 v3/vt3/vn3 ...							//
		//******************************************************************// 
		if (line.compare(0, 2, L"f ") == 0)  //"f space"
		{
			WCHAR first[10];
			WCHAR slash1[10];
			WCHAR slash2[10];
			WCHAR slash3[10];
			WCHAR slash4[10];
			WCHAR slash5[10];
			WCHAR slash6[10];

			UINT v1, vt1, vn1, v2, vt2, vn2, v3, vt3, vn3;

			WCHAR oldStyleStr[200];
			wcscpy(oldStyleStr, line.c_str());
			swscanf(oldStyleStr, L"%2s%d%1s%d%1s%d%d%1s%d%1s%d%d%1s%d%1s%d", first,
				&v1, slash1, &vt1, slash2, &vn1,
				&v2, slash3, &vt2, slash4, &vn2,
				&v3, slash5, &vt3, slash6, &vn3);

			Index input;

			input.v = v1 - 1;
			input.vt = vt1 - 1;
			input.vn = vn1 - 1;

			if (newMaterial)
			{
				input.newMaterial = true;
				wcscpy(input.materialName, materialName);
				newMaterial = false;
			}

			vectorIndices.push_back(input);
			input.newMaterial = false;

			input.v = v2 - 1;
			input.vt = vt2 - 1;
			input.vn = vn2 - 1;
			vectorIndices.push_back(input);

			input.v = v3 - 1;
			input.vt = vt3 - 1;
			input.vn = vn3 - 1;
			vectorIndices.push_back(input);

			continue;
		}

		// get mtl file name
		if (line.compare(0, 7, L"mtllib ") == 0)
		{
			WCHAR first[10], mtlFileName[200];

			WCHAR oldStyleStr[200];
			wcscpy(oldStyleStr, line.c_str());
			swscanf(oldStyleStr, L"%7s%s", first, &mtlFileName);

			// read the mtl file
			// we need to prepend the folder name and stuff to the mtl file name
			WCHAR fullMtlFilePath[200];
			wcscpy(fullMtlFilePath, folder);
			wcsncat(fullMtlFilePath, mtlFileName, 200);

			readMtlFile(&vectorTextureFiles, fullMtlFilePath, folder);

			continue;
		}
	}


	//******************************************************************//
	// SIMPLIFICATION													//
	//******************************************************************//

	// so the problem with obj files is that the indices are stored as v/vt/vn
	// whereas directx can only handle indices of ...vertices (as far as I'm aware)
	// so what we need to do is find the indices that are completely unique (completely original combination of v/vt/vn)
	// and make them vertices, referencing them with 1 number instead of 3

	std::vector <SimpleVertex>	simplifiedVertices(0);
	std::vector <Index>			uniqueIndices(0);
	std::vector <MeshMaterial>		vectorSubsets(0);


	USHORT uniqueIndexCount = 0;
	USHORT subsetIndexCount = 0;
	USHORT totalIndexCount = 0;

	// for each index
	for (int i = 0; i < vectorIndices.size(); i++)
	{
		Index idx = vectorIndices[i];

		// if idx is the first index of a new material
		if (idx.newMaterial)
		{
			// if this is not the first subset, we need to set the index count of the previous subset
			if (vectorSubsets.size() > 0)
			{
				vectorSubsets.back().subset.ic = subsetIndexCount;
				subsetIndexCount = 0;
			}
		
			// create a new subset
			// this means we're creating a new subset even if we've already created one for the same material earlier on
			// (and if the obj file doesn't start with a material this will go horribly wrong)
			MeshMaterial meshMaterial;
			meshMaterial.subset.is = totalIndexCount;
			meshMaterial.subset.vs = simplifiedVertices.size();
			// also, we need to wipe the uniqueIndices vector, because we don't want indices from different subsets referencing the same vertices
			uniqueIndices.clear();
			uniqueIndexCount = 0;

			// find the material properties
			// which at the moment consists of just the texture
			for (int i = 0; i < vectorTextureFiles.size(); i++)
			{
				// if the material name matches
				if (wcscmp(idx.materialName, vectorTextureFiles[i].materialName) == 0)
				{
					Material * material = &vectorTextureFiles[i];
					if (material->hasTexture)
					{
						wcscpy(meshMaterial.textureFilePath, material->textureFilePath);
						meshMaterial.hasTexture = true;
					}

					//meshMaterial.subset.color = vectorTextureFiles[i].color;
				}
			}

			vectorSubsets.push_back(meshMaterial);
		}


		std::vector <Index> matchingV(0);

		// of uniqueIndices, find matching v
		for (size_t i = 0; i < uniqueIndices.size(); i++)
		{
			Index vert = uniqueIndices[i];
			if (idx.v == vert.v)
			{
				// add to matchingV
				matchingV.push_back(vert);
			}
		}

		std::vector <Index> matchingVn(0);
		// of the ones we found, find matching vn
		for (size_t i = 0; i < matchingV.size(); i++)
		{
			Index vert = matchingV[i];
			if (idx.vn == vert.vn)
			{
				// add to matchingVn
				matchingVn.push_back(vert);
			}
		}

		std::vector <Index> matchingVt(0);
		// of the ones we found, find matching vt
		for (size_t i = 0; i < matchingVn.size(); i++)
		{
			Index vert = matchingVn[i];
			if (idx.vt == vert.vt)
			{
				// add to matchingVn
				matchingVt.push_back(vert);
			}
		}

		USHORT thisIndex;

		// if matchingVt is empty then this is unique
		if (matchingVt.size() == 0)
		{
			// create a uniqueIndex
			Index uniqueIndex = idx;
			uniqueIndex.vertex = uniqueIndexCount;
			uniqueIndices.push_back(uniqueIndex);

			// this is where we also create the vertex
			SimpleVertex newVertex;
			// we have to get the data from the vectors
			newVertex.Pos = vectorVertices[idx.v];
			newVertex.TexUV = vectorUVs[idx.vt];
			newVertex.VecNormal = vectorNormals[idx.vn];
			
			simplifiedVertices.push_back(newVertex);

			// also do this
			thisIndex = uniqueIndexCount;
			uniqueIndexCount++;
		}
		else
		{
			// otherwise there should be one left, meaning we got a complete match
			// now we can reference that vertex instead
			thisIndex = matchingVt[0].vertex;
		}
		
		vectorIndices[i].vertex = thisIndex;
		subsetIndexCount++;
		totalIndexCount++;
	}

	// we need to set the index count of the final subset here
	// we're not checking if vectorSubsets.size() is zero because that should never happen!
	vectorSubsets.back().subset.ic = subsetIndexCount;

	//******************************************************************//
	// SUBSETS															//
	//******************************************************************//

	objMesh.numSs = vectorSubsets.size();
	objMesh.subsets = new ObjMeshSubset[objMesh.numSs];
	for (int i = 0; i < objMesh.numSs; i++)
	{
		objMesh.subsets[i] = vectorSubsets[i].subset;

		// also do the textures while we're here
		ObjMeshSubset * subset = &objMesh.subsets[i];
		subset->hastxtrz = vectorSubsets[i].hasTexture;

		if (subset->hastxtrz)
		{
			// create the texture resource
			D3DX11CreateShaderResourceViewFromFile(pd3dDevice,
				vectorSubsets[i].textureFilePath,
				NULL, NULL,
				&subset->txtr,		// This is returned.
				NULL);
			DXUT_SetDebugName(subset->txtr, "MESH_TEXTURE");
		}
	}

	//******************************************************************//
	// VERTICES															//
	//******************************************************************//

	objMesh.numVertices = simplifiedVertices.size();
	objMesh.vertices = new SimpleVertex[objMesh.numVertices];
	for (int i = 0; i < objMesh.numVertices; i++)
		objMesh.vertices[i] = simplifiedVertices[i];


	//******************************************************************//
	// INDICES															//
	//******************************************************************//

	objMesh.numIndices = vectorIndices.size();
	objMesh.indexes = new USHORT[objMesh.numIndices];
	for (int i = 0; i < objMesh.numIndices; i++)
		objMesh.indexes[i] = vectorIndices[i].vertex;


	//******************************************************************//
	// BUFFERS															//
	//******************************************************************//

	// Create the vertex buffer
	D3D11_BUFFER_DESC bd;
	ZeroMemory(&bd, sizeof(bd));
	bd.Usage = D3D11_USAGE_DEFAULT;
	bd.ByteWidth = sizeof(SimpleVertex) * objMesh.numVertices;
	bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
	bd.CPUAccessFlags = 0;
	D3D11_SUBRESOURCE_DATA InitData;
	ZeroMemory(&InitData, sizeof(InitData));
	InitData.pSysMem = objMesh.vertices;

	pd3dDevice->CreateBuffer(&bd, &InitData, &objMesh.vb);
	DXUT_SetDebugName(objMesh.vb, "VERTEX_BUFFER");

	// create the index buffer
	bd.Usage = D3D11_USAGE_DEFAULT;
	bd.ByteWidth = sizeof(USHORT) * objMesh.numIndices;

	bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
	bd.CPUAccessFlags = 0;
	InitData.pSysMem = objMesh.indexes;

	pd3dDevice->CreateBuffer(&bd, &InitData, &objMesh.ib);
	DXUT_SetDebugName(objMesh.ib, "INDEX_BUFFER");
}
Exemplo n.º 4
0
int main_convertor (int argc, char** argv)
{
	printf (".LNG Convertor " VERSION "\n");
	printf ("Copyright (C) 2005-2006 WARP ItSelf & Alex Yaroslavsky\n\n");

	if ( argc < 5 )
	{
		printf ("Usage: convertor feed_file hpp_file num_of_lng lng_file1 lng_file2 ...\n\r");
		return 0;
	}

	HANDLE hFeedFile = WINPORT(CreateFile) (
			MB2Wide(argv[1]).c_str(),
			GENERIC_WRITE,
			FILE_SHARE_READ,
			NULL,
			CREATE_ALWAYS,
			0,
			NULL
			);

	if ( hFeedFile == INVALID_HANDLE_VALUE )
	{
		printf ("ERROR: Can't create the feed file, exiting.\n\r");
		return 0;
	}


	HANDLE hHFile = WINPORT(CreateFile) (
			MB2Wide(argv[2]).c_str(),
			GENERIC_READ,
			FILE_SHARE_READ,
			NULL,
			OPEN_EXISTING,
			0,
			NULL
			);

	if ( hHFile == INVALID_HANDLE_VALUE )
	{
		printf ("ERROR: Can't open the header file, exiting.\n\r");
		return 0;
	}

	int dwLangs = atol(argv[3]);

	if ( dwLangs<=0 )
	{
		printf ("ERROR: Zero language files to process, exiting.\n\r");
		return 0;
	}

	DWORD dwRead;
	DWORD dwSize = WINPORT(GetFileSize) (hHFile, NULL);

	char *pHBuffer = (char*)malloc (dwSize+1);

	memset (pHBuffer, 0, dwSize+1);

	WINPORT(ReadFile) (hHFile, pHBuffer, dwSize, &dwRead, NULL);

	WINPORT(CloseHandle) (hHFile);

	char *lpStart = pHBuffer;

	LanguageEntry *pLangEntries = (LanguageEntry*)malloc (dwLangs*sizeof (LanguageEntry));

	memset (pLangEntries, 0, dwLangs*sizeof (LanguageEntry));

	HANDLE hFile;

	for (int i = 0; i < dwLangs; i++)
	{
		hFile = WINPORT(CreateFile) (
				MB2Wide(argv[4+i]).c_str(),
				GENERIC_READ,
				FILE_SHARE_READ,
				NULL,
				OPEN_EXISTING,
				0,
				NULL
				);

		if ( hFile != INVALID_HANDLE_VALUE )
		{
			dwSize = WINPORT(GetFileSize) (hFile, NULL);

			pLangEntries[i].lpBuffer = (char*)malloc (dwSize+1);
			pLangEntries[i].lpStart = pLangEntries[i].lpBuffer;

			memset (pLangEntries[i].lpBuffer, 0, dwSize+1);

			WINPORT(ReadFile) (hFile, pLangEntries[i].lpBuffer, dwSize, &dwRead, NULL);

			WINPORT(CloseHandle) (hFile);
		}
		else
			printf ("WARNING: Can't open the language file \"%s\", skiping\n\r", argv[4+i]);
	}

	char *lpTmp = (char*)malloc (2048);
	char *lpString;

	sprintf (lpTmp, "#hpp file name\r\n%s\r\n#number of languages\r\n%s\r\n", argv[2], argv[3]);

	WINPORT(WriteFile) (hFeedFile, lpTmp, strlen (lpTmp), &dwRead, NULL);

	for (int i = 0; i < dwLangs; i++)
	{
		if ( pLangEntries[i].lpBuffer ) //or we skipping
		{
			char *lpLngName, *lpLngDesc;

			sprintf (lpTmp, "#id:%d language file name, language name, language description\r\n%s", i, argv[4+i]);

			WINPORT(WriteFile) (hFeedFile, lpTmp, strlen (lpTmp), &dwRead, NULL);

			ReadLanguage (pLangEntries[i].lpStart, &lpLngName, &lpLngDesc);

			sprintf (lpTmp," %s %s\r\n", lpLngName, lpLngDesc);
			WINPORT(WriteFile) (hFeedFile, lpTmp, strlen (lpTmp), &dwRead, NULL);

			free (lpLngName);
			free (lpLngDesc);
		}
	}

	sprintf(lpTmp,"\r\n#head of the hpp file\r\n");

	WINPORT(WriteFile) (hFeedFile, lpTmp, strlen (lpTmp), &dwRead, NULL);

	while ( ReadFromBufferEx (lpStart, &lpString) )
	{
		if ( !strncmp (lpString,"enum",4) )
		{
			free(lpString);

			char *lpOldStart = lpStart;

			ReadFromBufferEx (lpStart, &lpString);

			if ( strstr(lpString, "{") )
				lpOldStart = lpStart;

			free(lpString);

			while ( ReadFromBufferEx (lpStart, &lpString,true,true) && !strstr (lpString, "};") )
				free(lpString);

			char *lpEnd = lpStart-2;

			while ( *lpEnd != '\r' && *lpEnd != '\n')
				lpEnd--;

			while ( *lpEnd == '\r' || *lpEnd == '\n')
				lpEnd--;

			while ( *lpEnd != '\r' && *lpEnd != '\n')
				lpEnd--;

			*(lpEnd+1)=0;


			sprintf (lpTmp, "\r\n#tail of the hpp file\r\n");

			WINPORT(WriteFile) (hFeedFile, lpTmp, strlen (lpTmp), &dwRead, NULL);

			while ( ReadFromBufferEx (lpStart, &lpString) )
			{
				sprintf (lpTmp, "htail:%s\r\n", lpString);

				WINPORT(WriteFile) (hFeedFile, lpTmp, strlen (lpTmp), &dwRead, NULL);

				free(lpString);
			}

			lpStart = lpOldStart;

			break;
		}
		else
		{
			sprintf(lpTmp, "hhead:%s\r\n", lpString);
			WINPORT(WriteFile) (hFeedFile, lpTmp, strlen (lpTmp), &dwRead, NULL);
		}

		free(lpString);
	}

	char *lpOldStart = lpStart;

	while ( true )
	{
		WINPORT(WriteFile) (hFeedFile, "\r\n", 2, &dwRead, NULL);

		lpOldStart = lpStart;

		while ( ReadFromBufferEx (lpStart, &lpString) )
		{
			TrimStart (lpString);

			if ( strstr (lpString, "//") != lpString ) // "//" at the beginning at the string -> copy, else it will be discarded
			{
				free(lpString);

				lpStart = lpOldStart;

			break;
			}
			else
			{
				sprintf (lpTmp, "h:%s\r\n", lpString);
				WINPORT(WriteFile) (hFeedFile, lpTmp, strlen (lpTmp), &dwRead, NULL);
			}

			free(lpString);

			lpOldStart = lpStart;
		}

		if ( ReadFromBufferEx (lpStart, &lpString) )
		{
			char *lpComment = strstr (lpString, "//");

			if ( lpComment )
				*lpComment = 0;

			char *lpComa = strchr (lpString, ',');

			if ( lpComa )
				*lpComa = 0;

			Trim (lpString);

			if ( !*lpString )
				continue;

			sprintf (lpTmp, "%s\r\n", lpString);

			WINPORT(WriteFile) (hFeedFile, lpTmp, strlen (lpTmp), &dwRead, NULL);

			free(lpString);

			while ( true )
			{
				bool bSame=true;

				for (int i = 0; i < dwLangs; i++)
				{
					if ( pLangEntries[i].lpBuffer ) // or we skipping, no file read
					{
						pLangEntries[i].lpOldStart = pLangEntries[i].lpStart;
						bSame = bSame && ReadFromBufferEx (pLangEntries[i].lpStart, &pLangEntries[i].lpString);
					}
				}

				for (int i = 1; bSame && i < dwLangs; i++)
				{
					if ( pLangEntries[i].lpBuffer ) // or we skipping, no file read
					{
						if ( !pLangEntries[i].lpString ||
								(pLangEntries[i].lpString[0] == '"') ||
								strcmp (pLangEntries[0].lpString,pLangEntries[i].lpString) )
							bSame=false;
					}
				}

				if ( !bSame )
				{
					for (int i = 0; i < dwLangs; i++)
					{
						pLangEntries[i].lpStart = pLangEntries[i].lpOldStart;

						if ( pLangEntries[i].lpString )
							free(pLangEntries[i].lpString);
					}

					break;
				}

				if ( *pLangEntries[0].lpString )
				{
					sprintf (lpTmp, "l:%s\r\n", pLangEntries[0].lpString);
					WINPORT(WriteFile) (hFeedFile, lpTmp, strlen (lpTmp), &dwRead, NULL);
				}

				for (int i = 0; i < dwLangs; i++)
					free (pLangEntries[i].lpString);
			}

			for (int i = 0; i < dwLangs; i++)
			{
				if ( pLangEntries[i].lpBuffer ) // or we skipping, no file read
				{
					while ( ReadFromBufferEx (
							pLangEntries[i].lpStart,
							&pLangEntries[i].lpString
							) && pLangEntries[i].lpString[0] != '"' )
					{
						sprintf(lpTmp,"ls:%s\r\n",pLangEntries[i].lpString);

						WINPORT(WriteFile) (hFeedFile, lpTmp, strlen (lpTmp), &dwRead, NULL);

						free(pLangEntries[i].lpString);
					}

					strmove(lpTmp,pLangEntries[i].lpString);

					FixQuotes(lpTmp);

					strcat(lpTmp,"\r\n");

					WINPORT(WriteFile) (hFeedFile, lpTmp, strlen (lpTmp), &dwRead, NULL);

					free(pLangEntries[i].lpString);
				}
			}
		}
		else
			break;
	}

	WINPORT(CloseHandle)(hFeedFile);

	free(pHBuffer);

	for (int i = 0; i < dwLangs; i++)
		free(pLangEntries[i].lpBuffer);

	return 0;
}