From 5e82f3339fb5b126694045c202da82bce860759e Mon Sep 17 00:00:00 2001 From: Lendemor Date: Tue, 15 Mar 2016 16:24:49 +0100 Subject: [PATCH] added loadMesh and loadMTL, not tested yet --- src/tools/loader.cpp | 277 +++++++++++++++++++++++++++++++++++++++++++ src/tools/loader.h | 4 + 2 files changed, 281 insertions(+) diff --git a/src/tools/loader.cpp b/src/tools/loader.cpp index 6f962fb..fe3d85d 100644 --- a/src/tools/loader.cpp +++ b/src/tools/loader.cpp @@ -3,7 +3,12 @@ #include #include #include +#include "../resourcemanager.h" #include +#include +#include +//#include +#include "../sparrowrenderer/src/texture.h" std::string* Loader::loadTextFile(const std::string &filename) { @@ -40,3 +45,275 @@ Image* Loader::loadImage(const std::string &filename, bool hasAlpha) } return img; } + +std::vector Loader::loadMesh(const std::string &filename){ + std::vector meshes; + //MeshLoader* loader = new MeshLoader(wavefrontFilename); + //loader->textureLoader.setTexturePath(fileInfo.absolutePath()); + std::vector pos; + std::vector norm; + std::vector tex; + +// char line[LINEBUFFER_LENGTH]; + std::string line; + + Material* defaultMat = RESOURCE_GET(Material, "default"); + if(defaultMat == NULL) + { + defaultMat = new PhongMaterial(); + RESOURCE_ADD(defaultMat,Material,"default"); + } + Material* currentMat = defaultMat; + + std::ifstream file(filename); + + if(!file.is_open()) + { + fprintf(stderr, "can't load %s.\n", filename.c_str()); + return meshes; + } + + MeshBuilder* currentMesh = new MeshBuilder(); + meshes.push_back(currentMesh); + currentMesh->setMaterial(currentMat); + + std::getline(file, line); + while(!file.eof()) + { + if(line.length() == 0) // line vide + { + std::getline(file, line); + continue; + } + + switch(line[0]) + { + case 'v': + //vertex attribute + switch(line[1]) + { + case ' ': // vertex position + { + glm::vec3 p; + std::sscanf(line.c_str(),"v %f %f %f",&(p.x),&(p.y),&(p.z)); + pos.push_back(p); + break; + } + case 't': // texCoord + { + glm::vec2 t; + std::sscanf(line.c_str(),"vt %f %f",&(t.x),&(t.y)); + tex.push_back(t); + break; + } + case 'n': // normal + { + glm::vec3 n; + std::sscanf(line.c_str(),"vn %f %f %f",&(n.x),&(n.y),&(n.z)); + norm.push_back(n); + break; + } + } + break; + case 'f': // face + { + int tab[9]; + std::sscanf(line.c_str(),"f %d/%d/%d %d/%d/%d %d/%d/%d",tab,tab+1,tab+2,tab+3,tab+4,tab+5,tab+6,tab+7,tab+8); + //TODO: check sscanf success + + int nb_vertices = currentMesh->positions.size(); + + currentMesh->addTriangle(nb_vertices, nb_vertices+1, nb_vertices+2); + for(int i=0; i<3; ++i) + { + if(norm.size() == 0) + { + if(tex.size() == 0) + currentMesh->addPosition(pos[tab[i]-1]); + else + currentMesh->addVertex(pos[tab[i]-1], tex[tab[i+1]-1]); + } + else + { + if(tex.size() == 0) + currentMesh->addVertex(pos[tab[i]-1], norm[tab[i+2]-1]); + else + currentMesh->addVertex(pos[tab[i]-1], norm[tab[i+2]-1], tex[tab[i+1]-1]); + } + } + } + break; + case 'g': + currentMesh = new MeshBuilder(); + meshes.push_back(currentMesh); + currentMesh->setMaterial(currentMat); + break; + case 'm': // mtllib + { + std::string mat_filename; + std::sscanf(line.c_str(),"m %s",mat_filename); + loadMTL(mat_filename); + break; + } + case 'u': + { + // usemtl + std::string mat_name; + std::sscanf(line.c_str(),"u %s",mat_name); + currentMat = RESOURCE_GET(Material, mat_name); + if(currentMat == NULL) + { + fprintf(stderr, "cannot find any material named : %s.\n", mat_name.c_str()); + currentMat = new PhongMaterial(); + RESOURCE_ADD(currentMat,Material,mat_name); + } + currentMesh->setMaterial(currentMat); + } + break; + default: + case '#': + // comment + break; + } + std::getline(file,line); + } + + for(std::size_t i=0; iindices.size() == 0) + { + meshes[i] = meshes.back(); + meshes.pop_back(); + --i; + } + } + return meshes; +} + +std::vector split(const std::string &line, char sep){ + std::vector tokens; + std::size_t start=0, end=0; + while((end = line.find(sep,start)) != std::string::npos){ + tokens.push_back(line.substr(start,end-start)); + start=end+1; + } + tokens.push_back(line.substr(start)); + return tokens; +} + +//load MTL +bool Loader::loadMTL(const std::string &filename) +{ +// char line[1024]; + std::string line; + std::ifstream file(filename); + + if(!file.is_open()) + { + fprintf(stderr, "can't load %s.\n", filename.c_str()); + return false; + } + + PhongMaterial* mat = NULL; + bool hasNormalMap = false; + + std::getline(file,line); + + while(!file.eof()) + { + if(line.length() == 0) + { + std::getline(file,line); + continue; + } + //QStringList tokens = line.split(' '); + std::vector tokens = split(line,' '); + + if(tokens[0].substr(0,1) == "#") + { + // this is a comment + } + else if((tokens[0] == "newmtl") && tokens.size() == 2) + { + mat = new PhongMaterial(); + RESOURCE_ADD(mat,Material,tokens[1]); + } + else if((tokens[0].compare("Ka") == 0) && tokens.size() == 4) + { + mat->ambient.r = std::stof(tokens[1]); + mat->ambient.g = std::stof(tokens[2]); + mat->ambient.b = std::stof(tokens[3]); + } + else if(tokens[0].compare("Kd") == 0 && tokens.size() == 4) + { + mat->diffuse.r = std::stof(tokens[1]); + mat->diffuse.g = std::stof(tokens[2]); + mat->diffuse.b = std::stof(tokens[3]); + } + else if(tokens[0].compare("Ks") == 0 && tokens.size() == 4) + { + mat->specular.r = std::stof(tokens[1]); + mat->specular.g = std::stof(tokens[2]); + mat->specular.b = std::stof(tokens[3]); + } + else if(tokens[0].compare("Ns") == 0 && tokens.size() == 2) + { + mat->shininess = std::stof(tokens[1]); + } + else if((tokens[0].substr(0,4) == "map_") && tokens.size() == 2) + { + if(tokens[0].compare("map_Ka") == 0){ + mat->ambient_texture = RESOURCE_GET(Texture,tokens[1]); + if (mat->ambient_texture == NULL){ + mat->ambient_texture = new Texture(loadImage(tokens[1])); + RESOURCE_ADD(mat->ambient_texture,Texture,tokens[1]); + } + } else if(tokens[0].compare("map_Kd") == 0) { + mat->diffuse_texture = RESOURCE_GET(Texture,tokens[1]); + if (mat->diffuse_texture == NULL){ + mat->diffuse_texture = new Texture(loadImage(tokens[1])); + RESOURCE_ADD(mat->diffuse_texture,Texture,tokens[1]); + } + } else if(tokens[0].compare("map_Ks") == 0) { + mat->specular_texture = RESOURCE_GET(Texture,tokens[1]); + if (mat->specular_texture == NULL){ + mat->specular_texture = new Texture(loadImage(tokens[1])); + RESOURCE_ADD(mat->specular_texture,Texture,tokens[1]); + } + } else if(tokens[0].compare("map_Normal") == 0) { + mat->normal_map = RESOURCE_GET(Texture,tokens[1]); + if (mat->normal_map == NULL){ + mat->normal_map = new Texture(loadImage(tokens[1])); + RESOURCE_ADD(mat->normal_map,Texture,tokens[1]); + } + hasNormalMap = true; + } else if(tokens[0].compare("map_d") == 0) { + mat->alpha_mask = RESOURCE_GET(Texture,tokens[1]); + if (mat->alpha_mask == NULL){ + mat->alpha_mask = new Texture(loadImage(tokens[1])); + RESOURCE_ADD(mat->alpha_mask,Texture,tokens[1]); + } + } else + fprintf(stderr, "unsupported material property : \"%s\"\n", tokens[0].c_str()); + } + else + fprintf(stderr, "unsupported material property : \"%s\"\n", tokens[0].c_str()); + + std::getline(file,line); + } + return hasNormalMap; +} + +/* +//glfinish +void temp_glfinish(){ + for(std::size_t i=0; iinitGL(); + todos[i].target = images[i]->texture; + delete images[i]; + } + } +} +*/ diff --git a/src/tools/loader.h b/src/tools/loader.h index 3afef05..62bfbab 100644 --- a/src/tools/loader.h +++ b/src/tools/loader.h @@ -2,14 +2,18 @@ #define LOADER_H #include +#include class Image; +class Mesh; class Loader { public: static std::string* loadTextFile(const std::string &filename); static Image* loadImage(const std::string &filename, bool hasAlpha = true); + static std::vector loadMesh(const std::string &filename); + static bool loadMTL(const std::string &filename); }; #endif // LOADER_H