diff --git a/LearnOpenGL/ResourceLoader.cpp b/LearnOpenGL/ResourceLoader.cpp index 12965917254d52380380fc0a3ed3e65ee3627a37..e251f3f110979f297cd0468a2b8482c82fba5bd5 100644 --- a/LearnOpenGL/ResourceLoader.cpp +++ b/LearnOpenGL/ResourceLoader.cpp @@ -31,167 +31,164 @@ std::string get_extension(const std::string &filePath) return filePath.substr(filePath.find_last_of(".") + 1); } -bool openObj(const std::string fileName, std::vector<glm::vec3> &vertices, std::vector<glm::vec2> &vertexTexCoord, std::vector<glm::vec3> &vertexNormals) +std::vector<int> tokenize_index(std::string &input, const char delim) { - vertices.clear(); - vertexTexCoord.clear(); - vertexNormals.clear(); + std::vector<int> result; + std::string token; + std::stringstream ss(input); - std::ifstream ifs; + while (getline(ss, token, delim)) + { + result.push_back(std::stoi(token)); + } + + return result; +} + +glm::vec2 string_to_vec2(std::vector<std::string> &input) +{ + glm::vec2 result; + + result.x = stof(input.at(0)); + result.y = stof(input.at(1)); + + return result; +} +glm::vec3 string_to_vec3(std::vector<std::string> &input) +{ + glm::vec3 result; + + result.x = stof(input.at(0)); + result.y = stof(input.at(1)); + result.z = stof(input.at(2)); + + return result; +} + +int parse_lines(std::ifstream &ifs, std::vector<glm::vec3> &vertices, std::vector<glm::vec2> &vertexTexCoord, std::vector<glm::vec3> &vertexNormals) +{ std::string line; + std::vector<std::string> tokens; + std::string op; - char op[3]; std::vector<glm::vec3> vertexIndices; std::vector<glm::vec2> vertexTexCoordIndices; std::vector<glm::vec3> vertexNormalIndices; - ifs.open("../Models/" + fileName); - - int charPos = 0; while (std::getline(ifs, line)) { if (line[0] == NULL || line[0] == '\n' || line[0] == '#' || line[0] == '!' || line[0] == '$' || line[0] == 'o' || line[0] == 'm' || line[0] == 'u') continue; - sscanf_s(line.c_str(), "%s", op, sizeof(op)); - - charPos = 0; - if ((charPos = line.find(' ')) != std::string::npos) - { - line.erase(0, charPos + 1); - } + tokens = parse_line(line); + op = tokens.at(0); + tokens.erase(tokens.begin() + 0); - if (line[0] == ' ') + if (op.compare("v") == 0) { - line.erase(0, 1); + vertexIndices.push_back(string_to_vec3(tokens)); } - - if (strcmp(op, "v") == false) + else if (op.compare("vt") == 0) { - glm::vec3 pos = { 0,0,0 }; - sscanf_s(line.c_str(), "%f %f %f", &pos.x, &pos.y, &pos.z); - vertexIndices.push_back(pos); + vertexTexCoordIndices.push_back(string_to_vec2(tokens)); } - else if (strcmp(op, "vn") == false) + else if (op.compare("vn") == 0) { - glm::vec3 pos = { 0,0,0 }; - sscanf_s(line.c_str(), "%f %f %f", &pos.x, &pos.y, &pos.z); - vertexNormalIndices.push_back(pos); + vertexNormalIndices.push_back(string_to_vec3(tokens)); } - else if (strcmp(op, "vt") == false) + else if (op.compare("f") == 0) { - glm::vec2 pos = { 0,0 }; - sscanf_s(line.c_str(), "%f %f", &pos.x, &pos.y); - vertexTexCoordIndices.push_back(pos); - } + std::vector<int> vertexInfo; - if (strncmp(op, "f", 1) == false) - { - int vIndex = 0, uvIndex = 0, vnIndex = 0; std::vector<int> faceVertexIndicies; std::vector<int> faceVertexTexCoordIndicies; std::vector<int> faceVertexNormalIndicies; - charPos = 0; - while ((charPos = line.find(' ')) != std::string::npos) + for (auto &elem : tokens) { - if (line.find("//") == std::string::npos) - { - sscanf_s(line.substr(0, charPos).c_str(), "%d%*[-/]%d%*[-/]%d", &vIndex, &uvIndex, &vnIndex); - line.erase(0, charPos + 1); - } - else - { - uvIndex = 0; + vertexInfo = tokenize_index(elem, '/'); - sscanf_s(line.substr(0, charPos).c_str(), "%d%*[-//]%d", &vIndex, &vnIndex); - line.erase(0, charPos + 1); - } - - if (vIndex >= 1) - { - faceVertexIndicies.push_back(vIndex - 1); - } - if (uvIndex >= 1) + if (vertexInfo.size() == 2) // maybe not included VertexTexCoord { - faceVertexTexCoordIndicies.push_back(uvIndex - 1); + faceVertexIndicies.push_back(vertexInfo.at(0) - 1); + faceVertexNormalIndicies.push_back(vertexInfo.at(2) - 1); } - if (vnIndex >= 1) + else if (vertexInfo.size() == 3) { - faceVertexNormalIndicies.push_back(vnIndex - 1); + faceVertexIndicies.push_back(vertexInfo.at(0) - 1); + faceVertexTexCoordIndicies.push_back(vertexInfo.at(1) - 1); + faceVertexNormalIndicies.push_back(vertexInfo.at(2) - 1); } } - if (faceVertexIndicies.size() == 3) + if (tokens.size() == 3) { vertices.push_back(vertexIndices[faceVertexIndicies[0]]); vertices.push_back(vertexIndices[faceVertexIndicies[1]]); vertices.push_back(vertexIndices[faceVertexIndicies[2]]); + + vertexTexCoord.push_back(vertexTexCoordIndices[faceVertexTexCoordIndicies[0]]); + vertexTexCoord.push_back(vertexTexCoordIndices[faceVertexTexCoordIndicies[1]]); + vertexTexCoord.push_back(vertexTexCoordIndices[faceVertexTexCoordIndicies[2]]); + + vertexNormals.push_back(vertexNormalIndices[faceVertexNormalIndicies[0]]); + vertexNormals.push_back(vertexNormalIndices[faceVertexNormalIndicies[1]]); + vertexNormals.push_back(vertexNormalIndices[faceVertexNormalIndicies[2]]); } - else if (faceVertexIndicies.size() == 4) + else if (tokens.size() == 4) // rarely, face has 4 vertices { vertices.push_back(vertexIndices[faceVertexIndicies[0]]); vertices.push_back(vertexIndices[faceVertexIndicies[1]]); vertices.push_back(vertexIndices[faceVertexIndicies[2]]); - vertices.push_back(vertexIndices[faceVertexIndicies[0]]); vertices.push_back(vertexIndices[faceVertexIndicies[2]]); vertices.push_back(vertexIndices[faceVertexIndicies[3]]); - } - else - { - GLchar infoLog[512] = { 0, }; - log_warn(infoLog, fileName + " : " + "faceVertexIndices.size() : " + std::to_string(faceVertexIndicies.size())); - } - if (faceVertexTexCoordIndicies.size() > 0) - { - if (faceVertexTexCoordIndicies.size() == 3) - { - vertexTexCoord.push_back(vertexTexCoordIndices[faceVertexTexCoordIndicies[0]]); - vertexTexCoord.push_back(vertexTexCoordIndices[faceVertexTexCoordIndicies[1]]); - vertexTexCoord.push_back(vertexTexCoordIndices[faceVertexTexCoordIndicies[2]]); - } - else if (faceVertexTexCoordIndicies.size() == 4) - { - vertexTexCoord.push_back(vertexTexCoordIndices[faceVertexTexCoordIndicies[0]]); - vertexTexCoord.push_back(vertexTexCoordIndices[faceVertexTexCoordIndicies[1]]); - vertexTexCoord.push_back(vertexTexCoordIndices[faceVertexTexCoordIndicies[2]]); - - vertexTexCoord.push_back(vertexTexCoordIndices[faceVertexTexCoordIndicies[0]]); - vertexTexCoord.push_back(vertexTexCoordIndices[faceVertexTexCoordIndicies[2]]); - vertexTexCoord.push_back(vertexTexCoordIndices[faceVertexTexCoordIndicies[3]]); - } - else - { - GLchar infoLog[512] = { 0, }; - log_warn(infoLog, fileName + " : " + "vertexTexCoordIndices.size() : " + std::to_string(faceVertexTexCoordIndicies.size())); - } - } + vertexTexCoord.push_back(vertexTexCoordIndices[faceVertexTexCoordIndicies[0]]); + vertexTexCoord.push_back(vertexTexCoordIndices[faceVertexTexCoordIndicies[1]]); + vertexTexCoord.push_back(vertexTexCoordIndices[faceVertexTexCoordIndicies[2]]); + vertexTexCoord.push_back(vertexTexCoordIndices[faceVertexTexCoordIndicies[0]]); + vertexTexCoord.push_back(vertexTexCoordIndices[faceVertexTexCoordIndicies[2]]); + vertexTexCoord.push_back(vertexTexCoordIndices[faceVertexTexCoordIndicies[3]]); - if (faceVertexNormalIndicies.size() == 3) - { - vertexNormals.push_back(vertexNormalIndices[faceVertexNormalIndicies[0]]); - vertexNormals.push_back(vertexNormalIndices[faceVertexNormalIndicies[1]]); - vertexNormals.push_back(vertexNormalIndices[faceVertexNormalIndicies[2]]); - } - else if (faceVertexNormalIndicies.size() == 4) - { vertexNormals.push_back(vertexNormalIndices[faceVertexNormalIndicies[0]]); vertexNormals.push_back(vertexNormalIndices[faceVertexNormalIndicies[1]]); vertexNormals.push_back(vertexNormalIndices[faceVertexNormalIndicies[2]]); - vertexNormals.push_back(vertexNormalIndices[faceVertexNormalIndicies[0]]); vertexNormals.push_back(vertexNormalIndices[faceVertexNormalIndicies[2]]); vertexNormals.push_back(vertexNormalIndices[faceVertexNormalIndicies[3]]); } - else - { - GLchar infoLog[512] = { 0, }; - log_warn(infoLog, fileName + " : " + "faceVertexNormalIndices.size() : " + std::to_string(faceVertexNormalIndicies.size())); - } } } + return true; +} + +std::vector<std::string> parse_line(std::string &line) +{ + std::vector<std::string> result; + std::stringstream ss(line); + std::string token; + + while (ss >> token) + { + result.push_back(token); + } + + return result; +} + +bool openObj(const std::string fileName, std::vector<glm::vec3> &vertices, std::vector<glm::vec2> &vertexTexCoord, std::vector<glm::vec3> &vertexNormals) +{ + vertices.clear(); + vertexTexCoord.clear(); + vertexNormals.clear(); + + std::ifstream ifs; + + ifs.open("../Models/" + fileName); + + parse_lines(ifs, vertices, vertexTexCoord, vertexNormals); + ifs.close(); return true; diff --git a/LearnOpenGL/ResourceLoader.h b/LearnOpenGL/ResourceLoader.h index 21b7fa35dd472153c3c27f5a45cafd7472e486ad..7c0308428fd141a893b5d6439e953dc08951f526 100644 --- a/LearnOpenGL/ResourceLoader.h +++ b/LearnOpenGL/ResourceLoader.h @@ -3,6 +3,7 @@ #include <string> #include <iostream> #include <fstream> +#include <sstream> #include <vector> #include <GL/glew.h> @@ -31,6 +32,11 @@ public: }; std::string get_extension(const std::string &filePath); +std::vector<int> tokenize_index(std::string &input, const char delim); +glm::vec2 string_to_vec2(std::vector<std::string> &input); +glm::vec3 string_to_vec3(std::vector<std::string> &input); +int parse_lines(std::ifstream &ifs, std::vector<glm::vec3> &vertices, std::vector<glm::vec2> &vertexTexCoord, std::vector<glm::vec3> &vertexNormals); +std::vector<std::string> parse_line(std::string &line); bool openObj(const std::string fileName, std::vector<glm::vec3> &vertices, std::vector<glm::vec2> &vertexTexCoord, std::vector<glm::vec3> &vertexNormals); Image *load_Image(std::string fileName, int *width, int *height, int *nrChannels); void free_image(Image *img); \ No newline at end of file