From 8929717c9f53d66f45ba224deed308830ca2b791 Mon Sep 17 00:00:00 2001 From: Anakin Date: Sun, 13 Nov 2016 12:15:33 +0100 Subject: [PATCH] handle clustered models --- MshViewer/Header/Object.h | 18 ++-- MshViewer/Source/Object.cpp | 48 +++++---- MshViewer/Source/OpenGlController.cpp | 139 +++++++++++++++----------- MshViewer/main.cpp | 2 +- README.md | 10 +- Release/Msh/cluster.msh | Bin 0 -> 2484 bytes 6 files changed, 123 insertions(+), 94 deletions(-) create mode 100644 Release/Msh/cluster.msh diff --git a/MshViewer/Header/Object.h b/MshViewer/Header/Object.h index 36b8c8b..c4157ea 100644 --- a/MshViewer/Header/Object.h +++ b/MshViewer/Header/Object.h @@ -20,17 +20,21 @@ struct ChunkHeader { std::streampos position; }; +struct Segment { + std::string texture = ""; + float* vertex = nullptr; + float* uv = nullptr; + std::uint32_t* mesh = nullptr; + std::uint32_t meshSize = 0; +}; + struct Modl { std::string name = ""; std::string parent = ""; Mtyp type = null; std::int32_t renderFlags = -1; glm::mat4 m4x4Translation = glm::mat4(1.0f); - std::string texture = ""; - float* vertex = nullptr; - float* uv = nullptr; - std::uint32_t* mesh = nullptr; - std::uint32_t meshSize = 0; + std::vector segmLst; }; @@ -55,8 +59,8 @@ private: void analyseGeomChunks(Modl* dataDestination, std::list &chunkList); void analyseSegmChunks(Modl* dataDestination, std::list &chunkList); void analyseClthChunks(Modl* dataDestination, std::list &chunkList); - void readVertex(Modl* dataDestination, std::streampos position); - void readUV(Modl* dataDestination, std::streampos position); + void readVertex(Segment* dataDestination, std::streampos position); + void readUV(Segment* dataDestination, std::streampos position); public: diff --git a/MshViewer/Source/Object.cpp b/MshViewer/Source/Object.cpp index ed468bb..330d007 100644 --- a/MshViewer/Source/Object.cpp +++ b/MshViewer/Source/Object.cpp @@ -369,6 +369,8 @@ void Object::analyseGeomChunks(Modl * dataDestination, std::list& void Object::analyseSegmChunks(Modl * dataDestination, std::list& chunkList) { + Segment* tempData = new Segment; + for (std::list::iterator it = chunkList.begin(); it != chunkList.end(); it++) { /*if (!strcmp("SHDW", (*it)->name)) @@ -396,16 +398,16 @@ void Object::analyseSegmChunks(Modl * dataDestination, std::list& if (vTextures.size() <= tempIndex) { std::cout << "warning texture index <" << tempIndex << "> unknown" << std::endl; - dataDestination->texture = ""; + tempData->texture = ""; continue; } - dataDestination->texture = vTextures[tempIndex]; + tempData->texture = vTextures[tempIndex]; continue; } if (!strcmp("POSL", (*it)->name)) { - readVertex(dataDestination, (*it)->position); + readVertex(tempData, (*it)->position); continue; } @@ -420,7 +422,7 @@ void Object::analyseSegmChunks(Modl * dataDestination, std::list& if (!strcmp("UV0L", (*it)->name)) { - readUV(dataDestination, (*it)->position); + readUV(tempData, (*it)->position); continue; } @@ -429,11 +431,11 @@ void Object::analyseSegmChunks(Modl * dataDestination, std::list& fsMesh.seekg((*it)->position); fsMesh.seekg((*it)->position); - fsMesh.read(reinterpret_cast(&dataDestination->meshSize), sizeof(dataDestination->meshSize)); + fsMesh.read(reinterpret_cast(&tempData->meshSize), sizeof(tempData->meshSize)); - dataDestination->mesh = new std::uint32_t[dataDestination->meshSize]; + tempData->mesh = new std::uint32_t[tempData->meshSize]; - for (unsigned int i = 0; i < dataDestination->meshSize; i += 3) + for (unsigned int i = 0; i < tempData->meshSize; i += 3) { std::uint16_t tempValue[3]; fsMesh.read(reinterpret_cast(&tempValue[0]), sizeof(std::uint16_t)); @@ -446,18 +448,21 @@ void Object::analyseSegmChunks(Modl * dataDestination, std::list& tempValue[0] = (std::uint16_t(tempValue[0] << 1) >> 1); tempValue[1] = (std::uint16_t(tempValue[1] << 1) >> 1); - dataDestination->mesh[i] = (std::uint32_t)tempValue[0]; - dataDestination->mesh[i + 1] = (std::uint32_t)tempValue[1]; - dataDestination->mesh[i + 2] = (std::uint32_t)tempValue[2]; + tempData->mesh[i] = (std::uint32_t)tempValue[0]; + tempData->mesh[i + 1] = (std::uint32_t)tempValue[1]; + tempData->mesh[i + 2] = (std::uint32_t)tempValue[2]; } continue; } } + dataDestination->segmLst.push_back(tempData); } void Object::analyseClthChunks(Modl * dataDestination, std::list& chunkList) { + Segment* tempData = new Segment; + for (std::list::iterator it = chunkList.begin(); it != chunkList.end(); it++) { if (!strcmp("CTEX", (*it)->name)) @@ -466,42 +471,43 @@ void Object::analyseClthChunks(Modl * dataDestination, std::list& char* buffer = new char[(*it)->size]; *buffer = { 0 }; fsMesh.read(buffer, (*it)->size); - dataDestination->texture = buffer; + tempData->texture = buffer; delete buffer; continue; } if (!strcmp("CPOS", (*it)->name)) { - readVertex(dataDestination, (*it)->position); + readVertex(tempData, (*it)->position); continue; } if (!strcmp("CUV0", (*it)->name)) { - readUV(dataDestination, (*it)->position); + readUV(tempData, (*it)->position); continue; } if (!strcmp("CMSH", (*it)->name)) { fsMesh.seekg((*it)->position); - fsMesh.read(reinterpret_cast(&dataDestination->meshSize), sizeof(dataDestination->meshSize)); + fsMesh.read(reinterpret_cast(&tempData->meshSize), sizeof(tempData->meshSize)); - dataDestination->mesh = new std::uint32_t[dataDestination->meshSize * 3]; + tempData->mesh = new std::uint32_t[tempData->meshSize * 3]; - for (unsigned int i = 0; i < dataDestination->meshSize; i += 3) + for (unsigned int i = 0; i < tempData->meshSize; i += 3) { - fsMesh.read(reinterpret_cast(&dataDestination->mesh[i]), sizeof(std::uint32_t)); - fsMesh.read(reinterpret_cast(&dataDestination->mesh[i + 1]), sizeof(std::uint32_t)); - fsMesh.read(reinterpret_cast(&dataDestination->mesh[i + 2]), sizeof(std::uint32_t)); + fsMesh.read(reinterpret_cast(&tempData->mesh[i]), sizeof(std::uint32_t)); + fsMesh.read(reinterpret_cast(&tempData->mesh[i + 1]), sizeof(std::uint32_t)); + fsMesh.read(reinterpret_cast(&tempData->mesh[i + 2]), sizeof(std::uint32_t)); } continue; } } + dataDestination->segmLst.push_back(tempData); } -void Object::readVertex(Modl* dataDestination, std::streampos position) +void Object::readVertex(Segment* dataDestination, std::streampos position) { std::uint32_t tempSize; fsMesh.seekg(position); @@ -513,7 +519,7 @@ void Object::readVertex(Modl* dataDestination, std::streampos position) fsMesh.read(reinterpret_cast(&dataDestination->vertex[i]), sizeof(float)); } -void Object::readUV(Modl* dataDestination, std::streampos position) +void Object::readUV(Segment* dataDestination, std::streampos position) { std::uint32_t tempSize; fsMesh.seekg(position); diff --git a/MshViewer/Source/OpenGlController.cpp b/MshViewer/Source/OpenGlController.cpp index b752a11..11da94a 100644 --- a/MshViewer/Source/OpenGlController.cpp +++ b/MshViewer/Source/OpenGlController.cpp @@ -114,9 +114,17 @@ void OpenGLController::deleteVectors() Modl* cursor = vModels.back(); vModels.pop_back(); - delete cursor->uv; - delete cursor->mesh; - delete cursor->vertex; + while (!cursor->segmLst.empty()) + { + Segment* segmCuror = cursor->segmLst.back(); + cursor->segmLst.pop_back(); + + delete segmCuror->uv; + delete segmCuror->mesh; + delete segmCuror->vertex; + delete segmCuror; + } + delete cursor; } @@ -294,29 +302,36 @@ void OpenGLController::updateScene() glUniform1i(gluiSamplerID, 0); int instanceOffset(0); + int textureIndex(0); for (unsigned int modelIndex = 0; modelIndex < vModels.size(); modelIndex++) { - // give texture to the shader - glTexImage2D(GL_TEXTURE_2D, - 0, - vTextures[modelIndex]->alpha ? GL_RGBA : GL_RGB, - vTextures[modelIndex]->width, - vTextures[modelIndex]->height, - 0, - vTextures[modelIndex]->alpha ? GL_BGRA : GL_BGR, - GL_UNSIGNED_BYTE, - vTextures[modelIndex]->data->data() - ); + for (auto& segIt : vModels[modelIndex]->segmLst) + { + // give texture to the shader + glTexImage2D( + GL_TEXTURE_2D, + 0, + vTextures[textureIndex]->alpha ? GL_RGBA : GL_RGB, + vTextures[textureIndex]->width, + vTextures[textureIndex]->height, + 0, + vTextures[textureIndex]->alpha ? GL_BGRA : GL_BGR, + GL_UNSIGNED_BYTE, + vTextures[textureIndex]->data->data() + ); - glGenerateMipmap(GL_TEXTURE_2D); + glGenerateMipmap(GL_TEXTURE_2D); - // give the MVP to the shader - glUniformMatrix4fv(gluiMatrixID, 1, GL_FALSE, &getMVPMatrix(modelIndex)[0][0]); + // give the MVP to the shader + glUniformMatrix4fv(gluiMatrixID, 1, GL_FALSE, &getMVPMatrix(modelIndex)[0][0]); - glDrawArrays(GL_TRIANGLES, instanceOffset, vModels[modelIndex]->meshSize); + glDrawArrays(GL_TRIANGLES, instanceOffset, segIt->meshSize); - instanceOffset += vModels[modelIndex]->meshSize; + // recalulate counter + instanceOffset += segIt->meshSize; + textureIndex++; + } } glfwSwapBuffers(pWindow); @@ -343,27 +358,30 @@ void OpenGLController::loadMsh(const char * path) // collect vertex data of all models std::vector tempBufferData; - for (auto& it : vModels) + for (auto& modIt : vModels) { - for (unsigned int i = 0; i < it->meshSize; i++) + for (auto& segIt : modIt->segmLst) { - Vertex tempVertex; - tempVertex.position[0] = (GLfloat)it->vertex[it->mesh[i] * 3]; - tempVertex.position[1] = (GLfloat)it->vertex[it->mesh[i] * 3 + 1]; - tempVertex.position[2] = (GLfloat)it->vertex[it->mesh[i] * 3 + 2]; - - if (it->uv == NULL) + for (unsigned int i = 0; i < segIt->meshSize; i++) { - tempVertex.uv[0] = 1.0; - tempVertex.uv[1] = 1.0; - } - else - { - tempVertex.uv[0] = (GLfloat)it->uv[it->mesh[i] * 2]; - tempVertex.uv[1] = (GLfloat)it->uv[it->mesh[i] * 2 + 1]; - } + Vertex tempVertex; + tempVertex.position[0] = (GLfloat)segIt->vertex[segIt->mesh[i] * 3]; + tempVertex.position[1] = (GLfloat)segIt->vertex[segIt->mesh[i] * 3 + 1]; + tempVertex.position[2] = (GLfloat)segIt->vertex[segIt->mesh[i] * 3 + 2]; - tempBufferData.push_back(tempVertex); + if (segIt->uv == NULL) + { + tempVertex.uv[0] = 1.0; + tempVertex.uv[1] = 1.0; + } + else + { + tempVertex.uv[0] = (GLfloat)segIt->uv[segIt->mesh[i] * 2]; + tempVertex.uv[1] = (GLfloat)segIt->uv[segIt->mesh[i] * 2 + 1]; + } + + tempBufferData.push_back(tempVertex); + } } } @@ -379,35 +397,38 @@ void OpenGLController::loadMsh(const char * path) // get textures - for (auto& it : vModels) + for (auto& modIt : vModels) { - textureData* tempData = new textureData; - try + for (auto& segIt : modIt->segmLst) { - if (it->texture == "") - throw std::invalid_argument("no texture name"); + textureData* tempData = new textureData; + try + { + if (segIt->texture == "") + throw std::invalid_argument("no texture name"); - std::string tempPath = path; + std::string tempPath = path; - while (tempPath.back() != '/' && tempPath.back() != '\\') - tempPath.pop_back(); + while (tempPath.back() != '/' && tempPath.back() != '\\') + tempPath.pop_back(); - TextureTGA tempTex(std::string(tempPath + it->texture).c_str()); + 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(tempTex.getData()); + tempData->alpha = tempTex.hasAlpha(); + tempData->width = tempTex.getWidth(); + tempData->height = tempTex.getHeight(); + tempData->data = new std::vector(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({ 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({ 0, 0, 255, 255 }); - } - - vTextures.push_back(tempData); } } diff --git a/MshViewer/main.cpp b/MshViewer/main.cpp index c23d154..4a166c9 100644 --- a/MshViewer/main.cpp +++ b/MshViewer/main.cpp @@ -17,7 +17,7 @@ int main(int argc, char** argv) else scene = OpenGLController::getInstance(); - scene->loadMsh("..\\Release\\Msh\\structured.msh"); + scene->loadMsh("..\\Release\\Msh\\cluster.msh"); do { scene->updateScene(); diff --git a/README.md b/README.md index 78a4fb7..f8cb589 100644 --- a/README.md +++ b/README.md @@ -13,11 +13,11 @@ Feel free to use my code the way you like. But remember i used some public libra licence, too. ### To Do -- crashing sometimes - no idea why, +- cluster seam to use wrong textures +- cloth testing +- colisions are displayed (dont touch hiden things) - bones are not triangulated, - nulls are not triangulated, -- crash when loading trooper, -- display cloth testing - integrate into a software: -> gui open file ( + drag and drop), -> list all msh under a directory, @@ -25,6 +25,4 @@ licence, too. -> display colisions, -> lights, -> handle render flags, -- draw more then one model, -- use different textures for one or multiple models, -- take a look at destruction + diff --git a/Release/Msh/cluster.msh b/Release/Msh/cluster.msh new file mode 100644 index 0000000000000000000000000000000000000000..c073ae3c2d02cfcc9d6348f9f979e72c89fae64f GIT binary patch literal 2484 zcmcIlO>5Lp6utdW6a-y3C@x$JigadNC?icWCNon=W`-on=*EsUh#;+m49ucJen3SK z1S>B50d?gM=zxDga3!=G>C(Lj-jmG5mzdUA+6Q;e{Yc(<=iT=*9m{mLP7^s^r}m!F zTk5tR6H(W2tn-ZCO0XI{d|>(3`1x8G1*o-L!#Tq^!-kmXhtX{I2GM)00vOnIGQ6ogNQ&#Gh^zHx)|^?F?sBfSXfC%8kBNYd6Pi z&2TtcP1*P7uN@zMI~)ZW{-V9FA2C1neyZPHi~j6=5qI_YxZAw<3AxiVZJiIfzv~$dBhVoT|xM&p$?Or_>->dDDw~xb=`%2T=dM{dkZ$cGg!~Y?y`32 z^P9!+@&#?@)~g0$AY$aD?)h#XX9C|Dif7_kn&aPj%IoD%5f$j2@Jo8m@;QltiT}4= z;!&tm&Bys?RJ|8j6LfuGjnIi0h!}aPm(`0s%<0vq>z^>fS1q5D7?|ttKXnqnBmWJt z;*+WuecZeKHtFNb-HL`7h`u5(^|E^Bm^G(2Sv%IxrcX`$d`*pWdTBc1ZSi=nQogG9 zJ8MEeH&`S3i8wvSmE>GYy{ul`;REze{zr56JeSi}v=^#g=tMuEEA4Y7=_}&2&uP7^ zUVKXr(5tgv(F_z{@{&t1tCx5jPP3}_>ek1`&+Sg*_1PENul02eF%U8GQr}PS9lL5{ GCBFdzx&93R literal 0 HcmV?d00001