faster method for texture handling
This commit is contained in:
		| @@ -21,7 +21,7 @@ struct ChunkHeader { | |||||||
| }; | }; | ||||||
|  |  | ||||||
| struct Segment { | struct Segment { | ||||||
| 	std::string texture			= ""; | 	std::uint32_t textureIndex	= 0; | ||||||
| 	float* vertex				= nullptr; | 	float* vertex				= nullptr; | ||||||
| 	float* uv					= nullptr; | 	float* uv					= nullptr; | ||||||
| 	std::uint32_t* mesh			= nullptr; | 	std::uint32_t* mesh			= nullptr; | ||||||
| @@ -65,5 +65,6 @@ private: | |||||||
|  |  | ||||||
| public: | public: | ||||||
| 	std::vector<Modl*> getModels() const; | 	std::vector<Modl*> getModels() const; | ||||||
|  | 	std::vector<std::string> getTextureList() const; | ||||||
|  |  | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -393,15 +393,7 @@ void Object::analyseSegmChunks(Modl * dataDestination, std::list<ChunkHeader*>& | |||||||
| 		if (!strcmp("MATI", (*it)->name)) | 		if (!strcmp("MATI", (*it)->name)) | ||||||
| 		{ | 		{ | ||||||
| 			fsMesh.seekg((*it)->position); | 			fsMesh.seekg((*it)->position); | ||||||
| 			std::uint32_t tempIndex; | 			fsMesh.read(reinterpret_cast<char*>(&tempData->textureIndex), sizeof(tempData->textureIndex)); | ||||||
| 			fsMesh.read(reinterpret_cast<char*>(&tempIndex), sizeof(tempIndex)); |  | ||||||
| 			if (vTextures.size() <= tempIndex) |  | ||||||
| 			{ |  | ||||||
| 				std::cout << "warning texture index <" << tempIndex << "> unknown" << std::endl; |  | ||||||
| 				tempData->texture = ""; |  | ||||||
| 				continue; |  | ||||||
| 			} |  | ||||||
| 			tempData->texture = vTextures[tempIndex]; |  | ||||||
| 			continue; | 			continue; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @@ -471,7 +463,25 @@ void Object::analyseClthChunks(Modl * dataDestination, std::list<ChunkHeader*>& | |||||||
| 			char* buffer = new char[(*it)->size]; | 			char* buffer = new char[(*it)->size]; | ||||||
| 			*buffer = { 0 }; | 			*buffer = { 0 }; | ||||||
| 			fsMesh.read(buffer, (*it)->size); | 			fsMesh.read(buffer, (*it)->size); | ||||||
| 			tempData->texture = buffer; |  | ||||||
|  | 			bool tempFound(false); | ||||||
|  |  | ||||||
|  | 			for (unsigned int index = 0; index < vTextures.size(); index++) | ||||||
|  | 			{ | ||||||
|  | 				if (!strcmp(buffer, vTextures[index].c_str())) | ||||||
|  | 				{ | ||||||
|  | 					tempData->textureIndex = index; | ||||||
|  | 					tempFound = true; | ||||||
|  | 					break; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			if (!tempFound) | ||||||
|  | 			{ | ||||||
|  | 				vTextures.push_back(std::string(buffer)); | ||||||
|  | 				tempData->textureIndex = vTextures.size() - 1; | ||||||
|  | 			} | ||||||
|  |  | ||||||
| 			delete buffer; | 			delete buffer; | ||||||
| 			continue; | 			continue; | ||||||
| 		} | 		} | ||||||
| @@ -540,6 +550,11 @@ std::vector<Modl*> Object::getModels() const | |||||||
| 	return vModls; | 	return vModls; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | std::vector<std::string> Object::getTextureList() const | ||||||
|  | { | ||||||
|  | 	return vTextures; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
| ///////////////////////////////////////////////////////////////////////// | ///////////////////////////////////////////////////////////////////////// | ||||||
| // public functions | // public functions | ||||||
|   | |||||||
| @@ -302,7 +302,6 @@ void OpenGLController::updateScene() | |||||||
| 	glUniform1i(gluiSamplerID, 0); | 	glUniform1i(gluiSamplerID, 0); | ||||||
|  |  | ||||||
| 	int instanceOffset(0); | 	int instanceOffset(0); | ||||||
| 	int textureIndex(0); |  | ||||||
|  |  | ||||||
| 	for (unsigned int modelIndex = 0; modelIndex < vModels.size(); modelIndex++) | 	for (unsigned int modelIndex = 0; modelIndex < vModels.size(); modelIndex++) | ||||||
| 	{ | 	{ | ||||||
| @@ -316,16 +315,18 @@ void OpenGLController::updateScene() | |||||||
| 		for (auto& segIt : vModels[modelIndex]->segmLst) | 		for (auto& segIt : vModels[modelIndex]->segmLst) | ||||||
| 		{ | 		{ | ||||||
| 			// give texture to the shader | 			// give texture to the shader | ||||||
|  | 			std::uint32_t tempTexIndex = segIt->textureIndex >= vTextures.size() ? vTextures.size() - 1 : segIt->textureIndex; | ||||||
|  | 			 | ||||||
| 			glTexImage2D( | 			glTexImage2D( | ||||||
| 				GL_TEXTURE_2D, | 				GL_TEXTURE_2D, | ||||||
| 				0, | 				0, | ||||||
| 				vTextures[textureIndex]->alpha ? GL_RGBA : GL_RGB, | 				vTextures[tempTexIndex]->alpha ? GL_RGBA : GL_RGB, | ||||||
| 				vTextures[textureIndex]->width, | 				vTextures[tempTexIndex]->width, | ||||||
| 				vTextures[textureIndex]->height, | 				vTextures[tempTexIndex]->height, | ||||||
| 				0, | 				0, | ||||||
| 				vTextures[textureIndex]->alpha ? GL_BGRA : GL_BGR, | 				vTextures[tempTexIndex]->alpha ? GL_BGRA : GL_BGR, | ||||||
| 				GL_UNSIGNED_BYTE, | 				GL_UNSIGNED_BYTE, | ||||||
| 				vTextures[textureIndex]->data->data() | 				vTextures[tempTexIndex]->data->data() | ||||||
| 			); | 			); | ||||||
|  |  | ||||||
| 			glGenerateMipmap(GL_TEXTURE_2D); | 			glGenerateMipmap(GL_TEXTURE_2D); | ||||||
| @@ -335,9 +336,8 @@ void OpenGLController::updateScene() | |||||||
|  |  | ||||||
| 			glDrawArrays(GL_TRIANGLES, instanceOffset, segIt->meshSize); | 			glDrawArrays(GL_TRIANGLES, instanceOffset, segIt->meshSize); | ||||||
|  |  | ||||||
| 			// recalulate counter | 			// increase the offset | ||||||
| 			instanceOffset += segIt->meshSize; | 			instanceOffset += segIt->meshSize; | ||||||
| 			textureIndex++; |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -350,11 +350,14 @@ void OpenGLController::loadMsh(const char * path) | |||||||
| 	// clean up old stuff first | 	// clean up old stuff first | ||||||
| 	deleteVectors(); | 	deleteVectors(); | ||||||
|  |  | ||||||
|  | 	std::vector<std::string> tempTexList; | ||||||
|  |  | ||||||
| 	// get all models | 	// get all models | ||||||
| 	try | 	try | ||||||
| 	{ | 	{ | ||||||
| 		Object obj(path); | 		Object obj(path); | ||||||
| 		vModels = obj.getModels(); | 		vModels = obj.getModels(); | ||||||
|  | 		tempTexList = obj.getTextureList(); | ||||||
| 	} | 	} | ||||||
| 	catch (std::invalid_argument e) | 	catch (std::invalid_argument e) | ||||||
| 	{ | 	{ | ||||||
| @@ -407,42 +410,46 @@ void OpenGLController::loadMsh(const char * path) | |||||||
| 	glBindBuffer(GL_ARRAY_BUFFER, 0); | 	glBindBuffer(GL_ARRAY_BUFFER, 0); | ||||||
|  |  | ||||||
|  |  | ||||||
| 	// get textures | 	// get textures path | ||||||
| 	for (auto& modIt : vModels) | 	std::string tempPath = path; | ||||||
|  |  | ||||||
|  | 	while (tempPath.back() != '/' && tempPath.back() != '\\') | ||||||
|  | 		tempPath.pop_back(); | ||||||
|  |  | ||||||
|  | 	// load all textures; | ||||||
|  | 	for (auto& texIt : tempTexList) | ||||||
| 	{ | 	{ | ||||||
| 		// we don't need textures from null, bones, shadowMesh and hidden things, since they are not displayed | 		textureData* tempData = new textureData; | ||||||
| 		if (modIt->type == null || modIt->type == bone || modIt->type == shadowMesh || modIt->renderFlags == 1) |  | ||||||
| 			continue; | 		try | ||||||
| 		for (auto& segIt : modIt->segmLst) |  | ||||||
| 		{ | 		{ | ||||||
| 			textureData* tempData = new textureData; | 			TextureTGA tempTex(std::string(tempPath + texIt).c_str()); | ||||||
| 			try |  | ||||||
| 			{ |  | ||||||
| 				if (segIt->texture == "") |  | ||||||
| 					throw std::invalid_argument("no texture name"); |  | ||||||
|  |  | ||||||
| 				std::string tempPath = path; | 			tempData->alpha = tempTex.hasAlpha(); | ||||||
|  | 			tempData->width = tempTex.getWidth(); | ||||||
| 				while (tempPath.back() != '/' && tempPath.back() != '\\') | 			tempData->height = tempTex.getHeight(); | ||||||
| 					tempPath.pop_back(); | 			tempData->data = new std::vector<std::uint8_t>(tempTex.getData()); | ||||||
|  |  | ||||||
| 				TextureTGA tempTex(std::string(tempPath + segIt->texture).c_str()); |  | ||||||
|  |  | ||||||
| 				tempData->alpha = tempTex.hasAlpha(); |  | ||||||
| 				tempData->width = tempTex.getWidth(); |  | ||||||
| 				tempData->height = tempTex.getHeight(); |  | ||||||
| 				tempData->data = new std::vector<std::uint8_t>(tempTex.getData()); |  | ||||||
| 			} |  | ||||||
| 			catch (std::invalid_argument e) |  | ||||||
| 			{ |  | ||||||
| 				GLubyte solidColor[4] = { 0, 0, 255, 255 }; |  | ||||||
| 				tempData->alpha = true; |  | ||||||
| 				tempData->width = 1; |  | ||||||
| 				tempData->height = 1; |  | ||||||
| 				tempData->data = new std::vector<std::uint8_t>({ 0, 0, 255, 255 }); |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			vTextures.push_back(tempData); |  | ||||||
| 		} | 		} | ||||||
|  | 		catch (std::invalid_argument e) | ||||||
|  | 		{ | ||||||
|  | 			GLubyte solidColor[4] = { 0, 0, 255, 255 }; | ||||||
|  | 			tempData->alpha = true; | ||||||
|  | 			tempData->width = 1; | ||||||
|  | 			tempData->height = 1; | ||||||
|  | 			tempData->data = new std::vector<std::uint8_t>({ 0, 0, 255, 255 }); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		vTextures.push_back(tempData); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	// add a solid default color at the end (maybe there is an invalid index later) | ||||||
|  | 	textureData* tempData = new textureData; | ||||||
|  | 	GLubyte solidColor[4] = { 0, 0, 255, 255 }; | ||||||
|  | 	tempData->alpha = true; | ||||||
|  | 	tempData->width = 1; | ||||||
|  | 	tempData->height = 1; | ||||||
|  | 	tempData->data = new std::vector<std::uint8_t>({ 0, 0, 255, 255 }); | ||||||
|  | 	vTextures.push_back(tempData); | ||||||
|  |  | ||||||
|  | 	tempTexList.clear(); | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Anakin
					Anakin