faster method for texture handling

This commit is contained in:
Anakin 2016-11-13 15:46:52 +01:00
parent 0f379ba04a
commit 806024f4f9
3 changed files with 75 additions and 52 deletions

View File

@ -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;
};

View File

@ -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

View File

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