faster method for texture handling
This commit is contained in:
		| @@ -21,7 +21,7 @@ struct ChunkHeader { | ||||
| }; | ||||
|  | ||||
| struct Segment { | ||||
| 	std::string texture			= ""; | ||||
| 	std::uint32_t textureIndex	= 0; | ||||
| 	float* vertex				= nullptr; | ||||
| 	float* uv					= nullptr; | ||||
| 	std::uint32_t* mesh			= nullptr; | ||||
| @@ -65,5 +65,6 @@ private: | ||||
|  | ||||
| public: | ||||
| 	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)) | ||||
| 		{ | ||||
| 			fsMesh.seekg((*it)->position); | ||||
| 			std::uint32_t tempIndex; | ||||
| 			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]; | ||||
| 			fsMesh.read(reinterpret_cast<char*>(&tempData->textureIndex), sizeof(tempData->textureIndex)); | ||||
| 			continue; | ||||
| 		} | ||||
|  | ||||
| @@ -471,7 +463,25 @@ void Object::analyseClthChunks(Modl * dataDestination, std::list<ChunkHeader*>& | ||||
| 			char* buffer = new char[(*it)->size]; | ||||
| 			*buffer = { 0 }; | ||||
| 			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; | ||||
| 			continue; | ||||
| 		} | ||||
| @@ -540,6 +550,11 @@ std::vector<Modl*> Object::getModels() const | ||||
| 	return vModls; | ||||
| } | ||||
|  | ||||
| std::vector<std::string> Object::getTextureList() const | ||||
| { | ||||
| 	return vTextures; | ||||
| } | ||||
|  | ||||
|  | ||||
| ///////////////////////////////////////////////////////////////////////// | ||||
| // public functions | ||||
|   | ||||
| @@ -302,7 +302,6 @@ void OpenGLController::updateScene() | ||||
| 	glUniform1i(gluiSamplerID, 0); | ||||
|  | ||||
| 	int instanceOffset(0); | ||||
| 	int textureIndex(0); | ||||
|  | ||||
| 	for (unsigned int modelIndex = 0; modelIndex < vModels.size(); modelIndex++) | ||||
| 	{ | ||||
| @@ -316,16 +315,18 @@ void OpenGLController::updateScene() | ||||
| 		for (auto& segIt : vModels[modelIndex]->segmLst) | ||||
| 		{ | ||||
| 			// give texture to the shader | ||||
| 			std::uint32_t tempTexIndex = segIt->textureIndex >= vTextures.size() ? vTextures.size() - 1 : segIt->textureIndex; | ||||
| 			 | ||||
| 			glTexImage2D( | ||||
| 				GL_TEXTURE_2D, | ||||
| 				0, | ||||
| 				vTextures[textureIndex]->alpha ? GL_RGBA : GL_RGB, | ||||
| 				vTextures[textureIndex]->width, | ||||
| 				vTextures[textureIndex]->height, | ||||
| 				vTextures[tempTexIndex]->alpha ? GL_RGBA : GL_RGB, | ||||
| 				vTextures[tempTexIndex]->width, | ||||
| 				vTextures[tempTexIndex]->height, | ||||
| 				0, | ||||
| 				vTextures[textureIndex]->alpha ? GL_BGRA : GL_BGR, | ||||
| 				vTextures[tempTexIndex]->alpha ? GL_BGRA : GL_BGR, | ||||
| 				GL_UNSIGNED_BYTE, | ||||
| 				vTextures[textureIndex]->data->data() | ||||
| 				vTextures[tempTexIndex]->data->data() | ||||
| 			); | ||||
|  | ||||
| 			glGenerateMipmap(GL_TEXTURE_2D); | ||||
| @@ -335,9 +336,8 @@ void OpenGLController::updateScene() | ||||
|  | ||||
| 			glDrawArrays(GL_TRIANGLES, instanceOffset, segIt->meshSize); | ||||
|  | ||||
| 			// recalulate counter | ||||
| 			// increase the offset | ||||
| 			instanceOffset += segIt->meshSize; | ||||
| 			textureIndex++; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @@ -350,11 +350,14 @@ void OpenGLController::loadMsh(const char * path) | ||||
| 	// clean up old stuff first | ||||
| 	deleteVectors(); | ||||
|  | ||||
| 	std::vector<std::string> tempTexList; | ||||
|  | ||||
| 	// get all models | ||||
| 	try | ||||
| 	{ | ||||
| 		Object obj(path); | ||||
| 		vModels = obj.getModels(); | ||||
| 		tempTexList = obj.getTextureList(); | ||||
| 	} | ||||
| 	catch (std::invalid_argument e) | ||||
| 	{ | ||||
| @@ -407,42 +410,46 @@ void OpenGLController::loadMsh(const char * path) | ||||
| 	glBindBuffer(GL_ARRAY_BUFFER, 0); | ||||
|  | ||||
|  | ||||
| 	// get textures | ||||
| 	for (auto& modIt : vModels) | ||||
| 	// get textures path | ||||
| 	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 | ||||
| 		if (modIt->type == null || modIt->type == bone || modIt->type == shadowMesh || modIt->renderFlags == 1) | ||||
| 			continue; | ||||
| 		for (auto& segIt : modIt->segmLst) | ||||
| 		textureData* tempData = new textureData; | ||||
|  | ||||
| 		try | ||||
| 		{ | ||||
| 			textureData* tempData = new textureData; | ||||
| 			try | ||||
| 			{ | ||||
| 				if (segIt->texture == "") | ||||
| 					throw std::invalid_argument("no texture name"); | ||||
| 			TextureTGA tempTex(std::string(tempPath + texIt).c_str()); | ||||
|  | ||||
| 				std::string tempPath = path; | ||||
|  | ||||
| 				while (tempPath.back() != '/' && tempPath.back() != '\\') | ||||
| 					tempPath.pop_back(); | ||||
|  | ||||
| 				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); | ||||
| 			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); | ||||
| 	} | ||||
|  | ||||
| 	// 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