#define STB_IMAGE_IMPLEMENTATION #include <stb_image.h> #include "ResourceLoader.h" Image::Image(int _width, int _height, int _cahnnel, unsigned char *_data) { width = _width; height = _height; channel = _cahnnel; data = _data; } int Image::getWidth() { return width; } int Image::getHeight() { return height; } unsigned char *Image::getData() { return data; } 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) { vertices.clear(); vertexTexCoord.clear(); vertexNormals.clear(); std::ifstream ifs; std::string line; 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); } if (line[0] == ' ') { line.erase(0, 1); } if (strcmp(op, "v") == false) { glm::vec3 pos = { 0,0,0 }; sscanf_s(line.c_str(), "%f %f %f", &pos.x, &pos.y, &pos.z); vertexIndices.push_back(pos); } else if (strcmp(op, "vn") == false) { glm::vec3 pos = { 0,0,0 }; sscanf_s(line.c_str(), "%f %f %f", &pos.x, &pos.y, &pos.z); vertexNormalIndices.push_back(pos); } else if (strcmp(op, "vt") == false) { glm::vec2 pos = { 0,0 }; sscanf_s(line.c_str(), "%f %f", &pos.x, &pos.y); vertexTexCoordIndices.push_back(pos); } 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) { 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; sscanf_s(line.substr(0, charPos).c_str(), "%d%*[-//]%d", &vIndex, &vnIndex); line.erase(0, charPos + 1); } } if (line.size() > 0) { 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; 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) { faceVertexTexCoordIndicies.push_back(uvIndex - 1); } if (vnIndex >= 1) { faceVertexNormalIndicies.push_back(vnIndex - 1); } } if (faceVertexIndicies.size() == 3) { vertices.push_back(vertexIndices[faceVertexIndicies[0]]); vertices.push_back(vertexIndices[faceVertexIndicies[1]]); vertices.push_back(vertexIndices[faceVertexIndicies[2]]); } else if (faceVertexIndicies.size() == 4) { 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())); } } 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())); } } } ifs.close(); return true; } Image *load_Image(std::string fileName, int *width, int *height, int *nrChannels) { fileName = "../Images/" + fileName; stbi_set_flip_vertically_on_load(true); unsigned char *data = stbi_load(fileName.c_str(), width, height, nrChannels, 0); if (data == NULL) { std::cout << "Failed to load texture : " + fileName << std::endl; } Image *img = new Image(*width, *height, *nrChannels, data); return img; } void free_image(Image *img) { stbi_image_free(img->getData()); free(img); }