diff --git a/NFAssetBuilder/NFAssetBuilder.vcxproj b/NFAssetBuilder/NFAssetBuilder.vcxproj index 74ffbda..45fdb10 100644 --- a/NFAssetBuilder/NFAssetBuilder.vcxproj +++ b/NFAssetBuilder/NFAssetBuilder.vcxproj @@ -62,6 +62,7 @@ true stdcpp17 $(ProjectDir)src\include;$(ProjectDir)dep\include;%(AdditionalIncludeDirectories) + true Console @@ -79,6 +80,7 @@ true stdcpp17 $(ProjectDir)src\include;$(ProjectDir)dep\include;%(AdditionalIncludeDirectories) + true Console @@ -91,13 +93,11 @@ - - diff --git a/NFAssetBuilder/NFAssetBuilder.vcxproj.filters b/NFAssetBuilder/NFAssetBuilder.vcxproj.filters index 372b91f..e9c24c6 100644 --- a/NFAssetBuilder/NFAssetBuilder.vcxproj.filters +++ b/NFAssetBuilder/NFAssetBuilder.vcxproj.filters @@ -18,9 +18,6 @@ Source Files - - Source Files - Source Files @@ -32,9 +29,6 @@ Header Files - - Header Files - Header Files diff --git a/NFAssetBuilder/src/Models.cpp b/NFAssetBuilder/src/Models.cpp index 0bd04c8..4d0f83a 100644 --- a/NFAssetBuilder/src/Models.cpp +++ b/NFAssetBuilder/src/Models.cpp @@ -4,6 +4,7 @@ #include #include #include +#include void cookModel(std::string& OBJin, std::string& MTLin, std::string& out) { std::vector obj(&OBJin[0], &OBJin[0] + OBJin.size()); @@ -156,8 +157,18 @@ void cookModel(std::string& OBJin, std::string& MTLin, std::string& out) { int matCount = 0; std::string modelHeader; - int numMats = (int)mats.size(); - modelHeader.append((char*)&numMats, sizeof(numMats)); + std::vector textures = getNeededTextures(MTLin); + std::string textureHeader; + + if (textures.empty()) + textureHeader = "none\n"; + else + for (const auto& curr : textures) + textureHeader.append(curr + (std::string)"\n"); + + modelHeader.append(textureHeader); + modelHeader.append("/ENDTEXTURES\n"); + modelHeader.append(std::to_string(mats.size()) + (std::string)"\n"); for (auto& m : mats) { std::string curr = m.first; @@ -192,13 +203,25 @@ void cookModel(std::string& OBJin, std::string& MTLin, std::string& out) { TempMaterial& curr2 = *m.second; - //Serialize this - //curr2.diffuseColor.x, curr2.diffuseColor.y, curr2.diffuseColor.z, curr2.shininess + std::string textureIndices; + if (!curr2.diffuseTextureName.empty()) + textureIndices.append(std::to_string((std::find(textures.begin(), textures.end(), curr2.diffuseTextureName) - textures.begin()) + 1) + (std::string)" "); + else + textureIndices.append(std::to_string(0) + (std::string)" "); + if (!curr2.specularTextureName.empty()) + textureIndices.append(std::to_string((std::find(textures.begin(), textures.end(), curr2.specularTextureName) - textures.begin()) + 1) + (std::string)" "); + else + textureIndices.append(std::to_string(0) + (std::string)" "); + if (!curr2.normalTextureName.empty()) + textureIndices.append(std::to_string((std::find(textures.begin(), textures.end(), curr2.normalTextureName) - textures.begin()) + 1) + (std::string)" "); + else + textureIndices.append(std::to_string(0) + (std::string)" "); - modelHeader.append((char*)&curr2.diffuseColor.x, sizeof(curr2.diffuseColor.x)); - modelHeader.append((char*)&curr2.diffuseColor.y, sizeof(curr2.diffuseColor.y)); - modelHeader.append((char*)&curr2.diffuseColor.z, sizeof(curr2.diffuseColor.z)); - modelHeader.append((char*)&curr2.shininess, sizeof(curr2.shininess)); + modelHeader.append(textureIndices); + modelHeader.append(std::to_string(curr2.diffuseColor.x) + (std::string)" "); + modelHeader.append(std::to_string(curr2.diffuseColor.y) + (std::string)" "); + modelHeader.append(std::to_string(curr2.diffuseColor.z) + (std::string)" "); + modelHeader.append(std::to_string(curr2.shininess) + (std::string)"\n"); size_t offset = vboPositions.size() / 3; vboPositions.insert(vboPositions.end(), curr2.outVB.begin(), curr2.outVB.end()); @@ -212,20 +235,23 @@ void cookModel(std::string& OBJin, std::string& MTLin, std::string& out) { delete m.second; matCount++; } + modelHeader.append("/ENDMATERIALS\n"); - size_t posSize = vboPositions.size() * sizeof(float); - size_t tcSize = vboTexCoords.size() * sizeof(float); - size_t normSize = vboNormals.size() * sizeof(float); - size_t tanSize = vboTangents.size() * sizeof(float); - size_t matIndicesSize = vboMaterialIndices.size() * sizeof(int); - size_t indicesSize = vboIndices.size() * sizeof(unsigned int); + unsigned int posSize = (unsigned int)vboPositions.size() * sizeof(float); + unsigned int tcSize = (unsigned int)vboTexCoords.size() * sizeof(float); + unsigned int normSize = (unsigned int)vboNormals.size() * sizeof(float); + unsigned int tanSize = (unsigned int)vboTangents.size() * sizeof(float); + unsigned int matIndicesSize = (unsigned int)vboMaterialIndices.size() * sizeof(int); + unsigned int indicesSize = (unsigned int)vboIndices.size() * sizeof(unsigned int); - modelHeader.append((char*)&posSize, sizeof(posSize)); - modelHeader.append((char*)&tcSize, sizeof(tcSize)); - modelHeader.append((char*)&normSize, sizeof(normSize)); - modelHeader.append((char*)&tanSize, sizeof(tanSize)); - modelHeader.append((char*)&matIndicesSize, sizeof(matIndicesSize)); - modelHeader.append((char*)&indicesSize, sizeof(indicesSize)); + modelHeader.append(std::to_string(posSize) + (std::string)" "); + modelHeader.append(std::to_string(tcSize) + (std::string)" "); + modelHeader.append(std::to_string(normSize) + (std::string)" "); + modelHeader.append(std::to_string(tanSize) + (std::string)" "); + modelHeader.append(std::to_string(matIndicesSize) + (std::string)" "); + modelHeader.append(std::to_string(vboIndices.size()) + (std::string)"\n"); + + modelHeader.append("/ENDHEADER\n"); out.append(modelHeader); out.append((char*)vboPositions.data(), posSize); @@ -278,7 +304,8 @@ void parseMaterials(std::unordered_map& mats, std::v } } -void getNeededImages(std::string mtl, std::set& set) { +std::vector getNeededTextures(std::string mtl) { + std::set tex; while (mtl.size()) { size_t pos = mtl.find("map_"); if (pos == std::string::npos) @@ -292,6 +319,15 @@ void getNeededImages(std::string mtl, std::set& set) { size_t pos2 = temp.find_last_of("/\\"); if (pos2 != std::string::npos) temp = temp.substr(pos2 + 1); - set.insert(temp); + tex.insert(temp); } + + std::vector out; + + if (tex.empty()) + return out; + else + for (const auto& curr : tex) + out.push_back(curr); + return out; } \ No newline at end of file diff --git a/NFAssetBuilder/src/Textures.cpp b/NFAssetBuilder/src/Textures.cpp deleted file mode 100644 index 5da6910..0000000 --- a/NFAssetBuilder/src/Textures.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "Textures.h" - -#define STB_IMAGE_IMPLEMENTATION -#include "stb_image.h" - -void cookTexture(const std::string& in, std::string& out) { - stbi_set_flip_vertically_on_load(true); - - int x, y, channels; - unsigned char* texture = stbi_load_from_memory((unsigned char*)&in[0], (int)in.size(), &x, &y, &channels, 0); - - out.append((char*)&x, sizeof(x)); - out.append((char*)&y, sizeof(y)); - out.append((char*)&channels, sizeof(channels)); - out.append((char*)texture, x * y * channels); - - stbi_image_free(texture); -} \ No newline at end of file diff --git a/NFAssetBuilder/src/Utility.cpp b/NFAssetBuilder/src/Utility.cpp index e19147c..2a9afd7 100644 --- a/NFAssetBuilder/src/Utility.cpp +++ b/NFAssetBuilder/src/Utility.cpp @@ -56,8 +56,6 @@ void writePack(const std::string& filename, std::string& in) { if (!out) Error("Pack \"" + filename + (std::string)"\" could not be written!"); - in.insert(0, "NFASSETPACK"); - Log("Encrypting..."); for (unsigned int i = 0; i < in.size(); i++) in[i] += 100; @@ -80,5 +78,8 @@ std::string getNewLine(std::stringstream& stringstream) { if (out[out.size() - 1] == '\r') out.erase(out.size() - 1); + if (out[0] == ' ') + out = out.substr(1); + return out; } \ No newline at end of file diff --git a/NFAssetBuilder/src/include/Models.h b/NFAssetBuilder/src/include/Models.h index 841db33..206843f 100644 --- a/NFAssetBuilder/src/include/Models.h +++ b/NFAssetBuilder/src/include/Models.h @@ -1,6 +1,4 @@ #pragma once -#include -#include #include #include @@ -30,4 +28,4 @@ struct TempMaterial { void cookModel(std::string& in, std::string& MTLin, std::string& out); void parseMaterials(std::unordered_map& mats, std::vector& mtl); -void getNeededImages(std::string mtl, std::set& set); \ No newline at end of file +std::vector getNeededTextures(std::string mtl); \ No newline at end of file diff --git a/NFAssetBuilder/src/include/Textures.h b/NFAssetBuilder/src/include/Textures.h deleted file mode 100644 index 95d6c84..0000000 --- a/NFAssetBuilder/src/include/Textures.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -#include - -void cookTexture(const std::string& in, std::string& out); \ No newline at end of file diff --git a/NFAssetBuilder/src/main.cpp b/NFAssetBuilder/src/main.cpp index 11a2e8e..8735ec9 100644 --- a/NFAssetBuilder/src/main.cpp +++ b/NFAssetBuilder/src/main.cpp @@ -1,25 +1,29 @@ +#include #include #include #include -#include #include #include #include "Utility.h" #include "Models.h" -#include "Textures.h" + +[[noreturn]] +void printHelp() { + std::cout << "Nothin' Fancy Asset Builder\n\nThis tool creates .nfpack files for the NF engine to " + "load at runtime. A pack gets created for each directory in the working directory if there " + "are only compatible files inside. Subdirectories are not ignored.\n\nFor more information, " + "refer to the Nothin' Fancy manual"; + + std::exit(0); +} int main(int argc, char* argv[]) { - Log("Starting up"); + if (argc > 1 && ((std::string)argv[1] == "-h" || (std::string)argv[1] == "/?")) + printHelp(); - if (argc > 1) - if ((std::string)argv[1] == "-h") { - Log("Nothin' Fancy Asset Builder\nThis tool creates .nfpack files for the NF engine to load " - "at runtime.\nA pack gets created for each directory in the working directory if there " - "are only compatible files inside.\nSubdirectories are not ignored."); - return 0; - } + Log("Starting up"); initCompressor(); @@ -35,7 +39,8 @@ int main(int argc, char* argv[]) { std::string currPackFilename = currDir.path().filename().string().append(".nfpack"); Log("Building pack " + currPackFilename); - std::unordered_map packFiles; + std::vector packFilenames; + std::vector packFileSizes; std::string currFileExtension; std::string currFileIn; std::string currPackOut; @@ -47,8 +52,8 @@ int main(int argc, char* argv[]) { std::filesystem::path relative = std::filesystem::relative(curr, currDir); std::string currFileName = relative.filename().string(); - for (auto& file : packFiles) - if (currFileName == file.first) + for (auto& file : packFilenames) + if (currFileName == file) Error("Duplicate asset \"" + currFileName + (std::string)"\" in pack!"); currFileExtension = relative.extension().string().substr(1); @@ -77,10 +82,11 @@ int main(int argc, char* argv[]) { Log("Cooking model..."); cookModel(currFileIn, mtl, currFileOut); } - else if (currFileExtension == "png" || currFileExtension == "jpg") - cookTexture(currFileIn, currFileOut); + else + currFileOut = currFileIn; - packFiles[currFileName] = currFileOut.size(); + packFilenames.push_back(currFileName); + packFileSizes.push_back((unsigned int)currFileOut.size()); currPackOut += currFileOut; @@ -94,19 +100,16 @@ int main(int argc, char* argv[]) { else Log("Finished gathering files"); + //Write pack header with asset names and sizes std::string header; - for (auto& currFile : packFiles) { - header += currFile.first; - header += ':'; - header.append((char*)&currFile.second, sizeof(size_t)); - header += ':'; + header += std::to_string(fileCount) + (std::string)"\n"; + for (unsigned int i = 0; i < packFilenames.size(); i++) { + header += packFilenames[i]; + header += '\n'; + header += std::to_string(packFileSizes[i]); + header += '\n'; } - header.erase(header.size() - 1); - header.append("/NFENDOFPACKHEADER"); - int headerTableSize = (int)header.size(); - header.insert(0, (char*)&headerTableSize, sizeof(headerTableSize)); - header.insert(0, (char*)&fileCount, sizeof(fileCount)); - + header.append("/ENDHEADER"); currPackOut.insert(0, header); writePack(currPackFilename, currPackOut); diff --git a/NothinFancy/assets/base/shaders/cubemapFragment.shader b/NothinFancy/assets/base/shaders/cubemapFragment.shader index 3f51c14..4fc69b7 100644 --- a/NothinFancy/assets/base/shaders/cubemapFragment.shader +++ b/NothinFancy/assets/base/shaders/cubemapFragment.shader @@ -8,9 +8,9 @@ out vec4 color; void main() { vec3 tc; - tc = vec3(-texCoord.x, texCoord.y, texCoord.z); - if (texCoord.y > 0.999999 || texCoord.y < -0.999999) { + tc = vec3(-texCoord.x, -texCoord.y, texCoord.z); + if (texCoord.y > 0.999999 || texCoord.y < -0.999999) tc = vec3(texCoord.x, texCoord.y, texCoord.z); - } + color = texture(cm, tc); } diff --git a/NFAssetBuilder/dep/include/stb_image.h b/NothinFancy/dep/include/stb_image.h similarity index 100% rename from NFAssetBuilder/dep/include/stb_image.h rename to NothinFancy/dep/include/stb_image.h diff --git a/NothinFancy/src/Assets.cpp b/NothinFancy/src/Assets.cpp index 21175c3..04e313b 100644 --- a/NothinFancy/src/Assets.cpp +++ b/NothinFancy/src/Assets.cpp @@ -51,34 +51,37 @@ namespace nf { } void AssetPack::load(const char* packName) { + NFLog("Loading asset pack \"" + (std::string)packName + (std::string)"\""); std::string path = "assets/" + (std::string)packName; - std::string packContents = readFile(path, true); + std::string packContents; + if (!readFile(path, packContents, true)) + NFError("Could not find pack file \"" + (std::string)packName + (std::string)"\"!") ; std::string packContentsOBJ = packContents; std::unordered_map cubemaps; std::unordered_map buttons; - unsigned int cubemapCount = 0; - unsigned int buttonCount = 0; - while (packContents.size()) { - packContents = packContents.substr(9); - size_t endAssetNamePos = packContents.find_first_of('\n'); - std::string assetName = packContents.substr(0, endAssetNamePos); - packContents = packContents.substr(endAssetNamePos + 1); - size_t extensionPos = assetName.find_first_of('.'); - std::string extension = assetName.substr(extensionPos + 1); - std::string assetContents; - size_t nextAssetPos = packContents.find("#NFASSET "); - if (nextAssetPos != std::string::npos) { - assetContents = packContents.substr(0, nextAssetPos - 1); - packContents = packContents.substr(nextAssetPos); - } - else { - assetContents = packContents; - packContents = ""; - } - unsigned int assetSize = (unsigned int)assetContents.size(); + unsigned int cubemapFaceCount = 0; + unsigned int buttonTextureCount = 0; - if (extension == "obj") + unsigned int assetCount = std::stoi(packContents.substr(0, packContents.find_first_of("\n"))); + + unsigned int endHeader = (unsigned int)packContents.find("/ENDHEADER"); + unsigned int headerLength = endHeader - ((unsigned int)packContents.find_first_of("\n") + 1); + std::stringstream header(packContents.substr(packContents.find_first_of("\n") + 1, headerLength)); + unsigned int assetPos = endHeader + 10; + for (unsigned int i = 0; i < assetCount; i++) { + std::string assetName; + std::getline(header, assetName); + std::string temp; + std::getline(header, temp); + unsigned int assetSize = std::stoi(temp); + + std::string extension = assetName.substr(assetName.find_last_of(".") + 1); + + if (extension == "obj") { + assetPos += assetSize; continue; + } + if (extension == "png" || extension == "jpg") { if (assetName.find("_cmfront") != std::string::npos || assetName.find("_cmback") != std::string::npos || assetName.find("_cmtop") != std::string::npos || assetName.find("_cmbottom") != std::string::npos || assetName.find("_cmleft") != std::string::npos || assetName.find("_cmright") != std::string::npos) { std::string cmName = assetName.substr(0, assetName.find('_')); @@ -91,40 +94,41 @@ namespace nf { NFError("Duplicate cubemap images in pack \"" + (std::string)packName + (std::string)"\"!"); if (assetName.find("_cmfront") != std::string::npos) { curr->frontData = new char[assetSize]; - std::memcpy(curr->frontData, &assetContents[0], assetSize); + std::memcpy(curr->frontData, &packContents[assetPos], assetSize); curr->frontSize = assetSize; } if (assetName.find("_cmback") != std::string::npos) { curr->backData = new char[assetSize]; - std::memcpy(curr->backData, &assetContents[0], assetSize); + std::memcpy(curr->backData, &packContents[assetPos], assetSize); curr->backSize = assetSize; } if (assetName.find("_cmtop") != std::string::npos) { curr->topData = new char[assetSize]; - std::memcpy(curr->topData, &assetContents[0], assetSize); + std::memcpy(curr->topData, &packContents[assetPos], assetSize); curr->topSize = assetSize; } if (assetName.find("_cmbottom") != std::string::npos) { curr->bottomData = new char[assetSize]; - std::memcpy(curr->bottomData, &assetContents[0], assetSize); + std::memcpy(curr->bottomData, &packContents[assetPos], assetSize); curr->bottomSize = assetSize; } if (assetName.find("_cmleft") != std::string::npos) { curr->leftData = new char[assetSize]; - std::memcpy(curr->leftData, &assetContents[0], assetSize); + std::memcpy(curr->leftData, &packContents[assetPos], assetSize); curr->leftSize = assetSize; } if (assetName.find("_cmright") != std::string::npos) { curr->rightData = new char[assetSize]; - std::memcpy(curr->rightData, &assetContents[0], assetSize); + std::memcpy(curr->rightData, &packContents[assetPos], assetSize); curr->rightSize = assetSize; } + assetPos += assetSize; curr->numImages++; if (curr->numImages == 6) m_assets[cmName + (std::string)".cm"] = curr; - cubemapCount++; + cubemapFaceCount++; continue; } else if (assetName.find("_buttonidle") != std::string::npos || assetName.find("_buttonhover") != std::string::npos || assetName.find("_buttonpressed") != std::string::npos) { @@ -139,30 +143,32 @@ namespace nf { NFError("Duplicate button images in pack \"" + (std::string)packName + (std::string)"\"!"); if (assetName.find("_buttonidle") != std::string::npos) { curr->idleTex.data = new char[assetSize]; - std::memcpy(curr->idleTex.data, &assetContents[0], assetSize); + std::memcpy(curr->idleTex.data, &packContents[assetPos], assetSize); curr->idleTex.size = assetSize; } if (assetName.find("_buttonhover") != std::string::npos) { curr->hoverTex.data = new char[assetSize]; - std::memcpy(curr->hoverTex.data, &assetContents[0], assetSize); + std::memcpy(curr->hoverTex.data, &packContents[assetPos], assetSize); curr->hoverTex.size = assetSize; } if (assetName.find("_buttonpressed") != std::string::npos) { curr->pressedTex.data = new char[assetSize]; - std::memcpy(curr->pressedTex.data, &assetContents[0], assetSize); + std::memcpy(curr->pressedTex.data, &packContents[assetPos], assetSize); curr->pressedTex.size = assetSize; } + assetPos += assetSize; curr->numImages++; if (curr->numImages == 3) m_assets[buttonName + (std::string)".button"] = curr; - buttonCount++; + buttonTextureCount++; continue; } ATexture* texture = new ATexture; texture->data = new char[assetSize]; - std::memcpy(texture->data, &assetContents[0], assetSize); + std::memcpy(texture->data, &packContents[assetPos], assetSize); + assetPos += assetSize; texture->size = assetSize; if (packName == "base.nfpack") texture->isBaseAsset = true; @@ -172,7 +178,8 @@ namespace nf { if (extension == "shader") { AShader* shader = new AShader; shader->data = new char[assetSize + 1]; - std::memcpy(shader->data, &assetContents[0], assetSize); + std::memcpy(shader->data, &packContents[assetPos], assetSize); + assetPos += assetSize; shader->data[assetSize] = '\0'; m_assets[assetName] = shader; continue; @@ -180,7 +187,8 @@ namespace nf { if (extension == "ttf") { AFont* font = new AFont; font->data = new char[assetSize]; - std::memcpy(font->data, &assetContents[0], assetSize); + std::memcpy(font->data, &packContents[assetPos], assetSize); + assetPos += assetSize; font->size = assetSize; if (packName == "base.nfpack") font->isBaseAsset = true; @@ -190,7 +198,8 @@ namespace nf { if (extension == "ogg" || extension == "wav") { ASound* sound = new ASound; sound->data = new char[assetSize]; - std::memcpy(sound->data, &assetContents[0], assetSize); + std::memcpy(sound->data, &packContents[assetPos], assetSize); + assetPos += assetSize; sound->size = assetSize; if (packName == "base.nfpack") sound->isBaseAsset = true; @@ -199,49 +208,50 @@ namespace nf { } NFError("Invalid asset extention in pack \"" + (std::string)packName + (std::string)"\"!"); } - if (cubemapCount % 6 != 0) + + if (cubemapFaceCount % 6 != 0) NFError("Could not find full cubemap in pack \"" + (std::string)packName + (std::string)"\"!"); - if (buttonCount % 3 != 0) + if (buttonTextureCount % 3 != 0) NFError("Could not find full button set in pack \"" + (std::string)packName + (std::string)"\"!"); - while (packContentsOBJ.size()) { - packContentsOBJ = packContentsOBJ.substr(9); - size_t endAssetNamePos = packContentsOBJ.find_first_of('\n'); - std::string assetName = packContentsOBJ.substr(0, endAssetNamePos); - packContentsOBJ = packContentsOBJ.substr(endAssetNamePos + 1); - size_t extensionPos = assetName.find_first_of('.'); - std::string extension = assetName.substr(extensionPos + 1); - std::string assetContents; - size_t nextAssetPos = packContentsOBJ.find("#NFASSET "); - if (nextAssetPos != std::string::npos) { - assetContents = packContentsOBJ.substr(0, nextAssetPos - 1); - packContentsOBJ = packContentsOBJ.substr(nextAssetPos); - } - else { - assetContents = packContentsOBJ; - packContentsOBJ = ""; - } + //Model pass after ATextures are loaded + + assetPos = endHeader + 10; + std::stringstream header2(packContents.substr(packContents.find_first_of("\n") + 1, headerLength)); + for (unsigned int i = 0; i < assetCount; i++) { + std::string assetName; + std::getline(header2, assetName); + std::string temp; + std::getline(header2, temp); + unsigned int assetSize = std::stoi(temp); + + std::string extension = assetName.substr(assetName.find_last_of(".") + 1); if (extension == "obj") { AModel* model = new AModel; - std::string textures = assetContents.substr(0, assetContents.find("\n")); + std::string textures = packContents.substr(assetPos, packContents.find("/ENDTEXTURES", assetPos) - assetPos - 1); if (textures != "none") { std::stringstream ss(textures); std::string curr; - while (ss >> curr) { - model->neededTextures[curr] = (ATexture*)m_assets[curr]; - } + while (std::getline(ss, curr)) + model->neededTextures.push_back((ATexture*)m_assets[curr]); } - assetContents = assetContents.substr(assetContents.find("\n") + 1); - size_t assetSize = assetContents.size(); + + unsigned int newStartPos = (unsigned int)packContents.find("/ENDTEXTURES", assetPos) + 13; + assetSize -= newStartPos - assetPos; + assetPos = newStartPos; model->data = new char[assetSize]; - std::memcpy(model->data, &assetContents[0], assetSize); + std::memcpy(model->data, &packContents[assetPos], assetSize); + assetPos += assetSize; model->size = assetSize; if (packName == "base.nfpack") model->isBaseAsset = true; m_assets[assetName] = model; continue; + } + + assetPos += assetSize; } m_loaded = true; diff --git a/NothinFancy/src/NFObject/Cubemap.cpp b/NothinFancy/src/NFObject/Cubemap.cpp index 9b71d6e..b73cacc 100644 --- a/NothinFancy/src/NFObject/Cubemap.cpp +++ b/NothinFancy/src/NFObject/Cubemap.cpp @@ -41,17 +41,15 @@ namespace nf { std::vector faces; int tempWidth, tempHeight, tempNChannels; unsigned char* tempData; - stbi_set_flip_vertically_on_load(false); + stbi_set_flip_vertically_on_load(true); tempData = stbi_load_from_memory((unsigned char*)cm.leftData, cm.leftSize, &tempWidth, &tempHeight, &tempNChannels, 0); faces.emplace_back(tempData, tempWidth, tempHeight, tempNChannels); tempData = stbi_load_from_memory((unsigned char*)cm.rightData, cm.rightSize, &tempWidth, &tempHeight, &tempNChannels, 0); faces.emplace_back(tempData, tempWidth, tempHeight, tempNChannels); - stbi_set_flip_vertically_on_load(true); tempData = stbi_load_from_memory((unsigned char*)cm.topData, cm.topSize, &tempWidth, &tempHeight, &tempNChannels, 0); faces.emplace_back(tempData, tempWidth, tempHeight, tempNChannels); tempData = stbi_load_from_memory((unsigned char*)cm.bottomData, cm.bottomSize, &tempWidth, &tempHeight, &tempNChannels, 0); faces.emplace_back(tempData, tempWidth, tempHeight, tempNChannels); - stbi_set_flip_vertically_on_load(false); tempData = stbi_load_from_memory((unsigned char*)cm.backData, cm.backSize, &tempWidth, &tempHeight, &tempNChannels, 0); faces.emplace_back(tempData, tempWidth, tempHeight, tempNChannels); tempData = stbi_load_from_memory((unsigned char*)cm.frontData, cm.frontSize, &tempWidth, &tempHeight, &tempNChannels, 0); diff --git a/NothinFancy/src/PhysicsEngine.cpp b/NothinFancy/src/PhysicsEngine.cpp index af0be3d..1e67c70 100644 --- a/NothinFancy/src/PhysicsEngine.cpp +++ b/NothinFancy/src/PhysicsEngine.cpp @@ -171,11 +171,11 @@ namespace nf { } } - void PhysicsEngine::addConvexMesh(Model* model, std::vector& vertices) { + void PhysicsEngine::addConvexMesh(Model* model, const float* vertices, unsigned int buffSize) { PxConvexMeshDesc desc; - desc.points.count = (unsigned int)vertices.size() / 3; + desc.points.count = (unsigned int)buffSize / 12; desc.points.stride = 3 * sizeof(float); - desc.points.data = &vertices[0]; + desc.points.data = vertices; desc.flags = PxConvexFlag::eCOMPUTE_CONVEX; PxDefaultMemoryOutputStream buf; @@ -187,14 +187,14 @@ namespace nf { m_convexMeshes[model] = mesh; } - void PhysicsEngine::addTriangleMesh(Model* model, std::vector& vertices, std::vector& indices) { + void PhysicsEngine::addTriangleMesh(Model* model, const float* vertices, unsigned int vertBuffSize, const unsigned int* indices, unsigned int indicesCount) { PxTriangleMeshDesc desc; - desc.points.count = (unsigned int)vertices.size() / 3; + desc.points.count = (unsigned int)vertBuffSize / 12; desc.points.stride = sizeof(float) * 3; - desc.points.data = &vertices[0]; - desc.triangles.count = (unsigned int)indices.size() / 3; + desc.points.data = vertices; + desc.triangles.count = (unsigned int)indicesCount / 3; desc.triangles.stride = sizeof(unsigned int) * 3; - desc.triangles.data = &indices[0]; + desc.triangles.data = indices; PxDefaultMemoryOutputStream buf; if (!m_cooking->cookTriangleMesh(desc, buf)) diff --git a/NothinFancy/src/Renderer/Model.cpp b/NothinFancy/src/Renderer/Model.cpp index d5ef314..ac392bb 100644 --- a/NothinFancy/src/Renderer/Model.cpp +++ b/NothinFancy/src/Renderer/Model.cpp @@ -14,293 +14,105 @@ namespace nf { Model::Model(AModel* model, bool physicsConvex, bool physicsTriangle) : - m_base(model->isBaseAsset), - m_newMtl("newmtl"), - m_newLine("\n") + m_base(model->isBaseAsset) { if (model->neededTextures.size() > 32) NFError("Model exceedes 32 texture limit!"); - std::vector file(model->data, model->data + model->size); - size_t mtlPos = std::search(file.begin(), file.end(), m_newMtl, m_newMtl + std::strlen(m_newMtl)) - file.begin(); - std::vector mtl(&file[mtlPos], &file[0] + file.size()); - std::unordered_map mats; - parseMaterials(mats, mtl); + std::string modelData(model->data, model->data + model->size); + std::string mats = modelData.substr(0, modelData.find("/ENDMATERIALS") - 1); - std::vector obj(&file[0], &file[mtlPos]); - std::vector vbRaw, tcRaw, vnRaw; - std::string usingMat; + createMaterials(mats, model); - bool tcPresent = false, vnPresent = false; - size_t position = 0; - while (true) { - size_t nextLine = std::search(obj.begin() + position, obj.end(), m_newLine, m_newLine + std::strlen(m_newLine)) - (obj.begin() + position); - if (!nextLine) - break; - std::vector line(&obj[position], &obj[position + nextLine]); - position += nextLine + 1; - std::stringstream ss(std::string(&line[0], line.size())); - std::string firstWord; - ss >> firstWord; + unsigned int vboSizesStart = (unsigned int)modelData.find("/ENDMATERIALS") + 14; + std::string vboSizes = modelData.substr(vboSizesStart, modelData.find("/ENDHEADER") - vboSizesStart - 1); - if (std::strcmp(&firstWord[0], "v") == 0) { - float x = 0.0f, y = 0.0f, z = 0.0f; - ss >> x >> y >> z; - vbRaw.push_back(x); - vbRaw.push_back(y); - vbRaw.push_back(z); - } - else if (std::strcmp(&firstWord[0], "vt") == 0) { - tcPresent = true; - float u = 0.0f, v = 0.0f; - ss >> u >> v; - tcRaw.push_back(u); - tcRaw.push_back(v); - } - else if (std::strcmp(&firstWord[0], "vn") == 0) { - vnPresent = true; - float x = 0.0f, y = 0.0f, z = 0.0f; - ss >> x >> y >> z; - vnRaw.push_back(x); - vnRaw.push_back(y); - vnRaw.push_back(z); - } - else if (std::strcmp(&firstWord[0], "usemtl") == 0) { - std::string matName; - ss >> matName; - usingMat = matName; - } - else if (std::strcmp(&firstWord[0], "f") == 0) { - if (!tcPresent) - NFError("No texture coordinates found in model!"); - if (!vnPresent) - NFError("No normals found in model!"); + unsigned int currPos = (unsigned int)modelData.find("/ENDHEADER") + 11; + unsigned int currSize = 0; + std::stringstream ss(vboSizes); - unsigned int vertexIndex[3], uvIndex[3], vnIndex[3]; - char temp; - ss >> vertexIndex[0] >> temp >> uvIndex[0] >> temp >> vnIndex[0] >> vertexIndex[1] >> temp >> uvIndex[1] >> temp >> vnIndex[1] >> vertexIndex[2] >> temp >> uvIndex[2] >> temp >> vnIndex[2]; - if (ss.rdbuf()->in_avail() > 1) - NFError("Model has non-triangle faces!"); - mats[usingMat]->vbIndices.push_back(vertexIndex[0]); - mats[usingMat]->vbIndices.push_back(vertexIndex[1]); - mats[usingMat]->vbIndices.push_back(vertexIndex[2]); - mats[usingMat]->tcIndices.push_back(uvIndex[0]); - mats[usingMat]->tcIndices.push_back(uvIndex[1]); - mats[usingMat]->tcIndices.push_back(uvIndex[2]); - mats[usingMat]->vnIndices.push_back(vnIndex[0]); - mats[usingMat]->vnIndices.push_back(vnIndex[1]); - mats[usingMat]->vnIndices.push_back(vnIndex[2]); - } - } + float* pos; + unsigned int posBuffSize; + unsigned int* indices; + unsigned int indicesCount; - for (auto& m : mats) { - std::string curr = m.first; - for (unsigned int i = 0; i < mats[curr]->vbIndices.size(); i++) { - unsigned int vertexIndex = mats[curr]->vbIndices[i]; - unsigned int uvIndex = mats[curr]->tcIndices[i]; - unsigned int vnIndex = mats[curr]->vnIndices[i]; - float vertexX = vbRaw[(vertexIndex - 1) * 3]; - float vertexY = vbRaw[(vertexIndex - 1) * 3 + 1]; - float vertexZ = vbRaw[(vertexIndex - 1) * 3 + 2]; - float vertexU = tcRaw[(uvIndex - 1) * 2]; - float vertexV = tcRaw[(uvIndex - 1) * 2 + 1]; - float vnX = vnRaw[(vnIndex - 1) * 3]; - float vnY = vnRaw[(vnIndex - 1) * 3 + 1]; - float vnZ = vnRaw[(vnIndex - 1) * 3 + 2]; - mats[curr]->unindexedVB.push_back(vertexX); - mats[curr]->unindexedVB.push_back(vertexY); - mats[curr]->unindexedVB.push_back(vertexZ); - mats[curr]->unindexedTC.push_back(vertexU); - mats[curr]->unindexedTC.push_back(vertexV); - mats[curr]->unindexedVN.push_back(vnX); - mats[curr]->unindexedVN.push_back(vnY); - mats[curr]->unindexedVN.push_back(vnZ); - } - - for (unsigned int i = 0; i * 9 < mats[curr]->unindexedVB.size(); i++) { - glm::vec3 pos1(mats[curr]->unindexedVB[i * 9], mats[curr]->unindexedVB[i * 9 + 1], mats[curr]->unindexedVB[i * 9 + 2]); - glm::vec2 uv1(mats[curr]->unindexedTC[i * 6], mats[curr]->unindexedTC[i * 6 + 1]); - glm::vec3 pos2(mats[curr]->unindexedVB[i * 9 + 3], mats[curr]->unindexedVB[i * 9 + 4], mats[curr]->unindexedVB[i * 9 + 5]); - glm::vec2 uv2(mats[curr]->unindexedTC[i * 6 + 2], mats[curr]->unindexedTC[i * 6 + 3]); - glm::vec3 pos3(mats[curr]->unindexedVB[i * 9 + 6], mats[curr]->unindexedVB[i * 9 + 7], mats[curr]->unindexedVB[i * 9 + 8]); - glm::vec2 uv3(mats[curr]->unindexedTC[i * 6 + 4], mats[curr]->unindexedTC[i * 6 + 5]); - - glm::vec3 edge1 = pos2 - pos1; - glm::vec3 edge2 = pos3 - pos1; - glm::vec2 delta1 = uv2 - uv1; - glm::vec2 delta2 = uv3 - uv1; - float f = 1.0f / (delta1.x * delta2.y - delta2.x * delta1.y); - float x = f * (delta2.y * edge1.x - delta1.y * edge2.x); - float y = f * (delta2.y * edge1.y - delta1.y * edge2.y); - float z = f * (delta2.y * edge1.z - delta1.y * edge2.z); - mats[curr]->unindexedTan.push_back(x); - mats[curr]->unindexedTan.push_back(y); - mats[curr]->unindexedTan.push_back(z); - mats[curr]->unindexedTan.push_back(x); - mats[curr]->unindexedTan.push_back(y); - mats[curr]->unindexedTan.push_back(z); - mats[curr]->unindexedTan.push_back(x); - mats[curr]->unindexedTan.push_back(y); - mats[curr]->unindexedTan.push_back(z); - } - } - - struct Vertex { - float x; - float y; - float z; - - float u; - float v; - - float vnX; - float vnY; - float vnZ; - - bool operator<(const Vertex other) const { - return std::memcmp((void*)this, (void*)&other, sizeof(Vertex)) > 0; - } - }; - std::vector vboPositions; - std::vector vboTexCoords; - std::vector vboNormals; - std::vector vboTangents; - std::vector vboMaterialIndices; - std::vector vboIndices; - int matCount = 0; - for (auto& m : mats) { - std::string curr = m.first; - std::map vertexMap; - for (unsigned int i = 0; i * 3 < mats[curr]->unindexedVB.size(); i++) { - Vertex currVertex = { mats[curr]->unindexedVB[(i * 3)], mats[curr]->unindexedVB[(i * 3) + 1], mats[curr]->unindexedVB[(i * 3) + 2], mats[curr]->unindexedTC[(i * 2)], mats[curr]->unindexedTC[(i * 2) + 1], mats[curr]->unindexedVN[(i * 3)], mats[curr]->unindexedVN[(i * 3) + 1], mats[curr]->unindexedVN[(i * 3) + 2] }; - bool found = false; - found = vertexMap.find(currVertex) != vertexMap.end(); - if (found) { - unsigned int index = vertexMap[currVertex]; - mats[curr]->outIB.push_back(index); - mats[curr]->ibCount++; - } - else { - mats[curr]->outVB.push_back(currVertex.x); - mats[curr]->outVB.push_back(currVertex.y); - mats[curr]->outVB.push_back(currVertex.z); - mats[curr]->outTC.push_back(currVertex.u); - mats[curr]->outTC.push_back(currVertex.v); - mats[curr]->outVN.push_back(currVertex.vnX); - mats[curr]->outVN.push_back(currVertex.vnY); - mats[curr]->outVN.push_back(currVertex.vnZ); - mats[curr]->outTan.push_back(mats[curr]->unindexedTan[(i * 3)]); - mats[curr]->outTan.push_back(mats[curr]->unindexedTan[(i * 3 + 1)]); - mats[curr]->outTan.push_back(mats[curr]->unindexedTan[(i * 3 + 2)]); - size_t index = (mats[curr]->outVB.size() / 3) - 1; - mats[curr]->outIB.push_back((unsigned int)index); - vertexMap[currVertex] = (unsigned int)index; - mats[curr]->ibCount++; - } - } - - TempMaterial& curr2 = *m.second; - ATexture* diffA = nullptr; - Texture* diff = nullptr; - if (curr2.diffuseTextureName.size()) { - diffA = model->neededTextures[curr2.diffuseTextureName]; - diff = new Texture(diffA); - } - ATexture* specA = nullptr; - Texture* spec = nullptr; - if (curr2.specularTextureName.size()) { - specA = model->neededTextures[curr2.specularTextureName]; - spec = new Texture(specA, true); - } - ATexture* normA = nullptr; - Texture* norm = nullptr; - if (curr2.normalTextureName.size()) { - normA = model->neededTextures[curr2.normalTextureName]; - norm = new Texture(normA, true); - } - m_materials.push_back(std::make_tuple(diff, spec, norm, curr2.diffuseColor.x, curr2.diffuseColor.y, curr2.diffuseColor.z, curr2.shininess)); - size_t offset = vboPositions.size() / 3; - vboPositions.insert(vboPositions.end(), curr2.outVB.begin(), curr2.outVB.end()); - vboTexCoords.insert(vboTexCoords.end(), curr2.outTC.begin(), curr2.outTC.end()); - vboNormals.insert(vboNormals.end(), curr2.outVN.begin(), curr2.outVN.end()); - vboTangents.insert(vboTangents.end(), curr2.outTan.begin(), curr2.outTan.end()); - vboMaterialIndices.insert(vboMaterialIndices.end(), curr2.outVB.size() / 3, matCount); - if (offset) - std::for_each(curr2.outIB.begin(), curr2.outIB.end(), [offset](unsigned int& out) { out += (unsigned int)offset; }); - vboIndices.insert(vboIndices.end(), curr2.outIB.begin(), curr2.outIB.end()); - delete m.second; - matCount++; - } - if (m_materials.size() > 32) - NFError("Model exceedes 32 material limit!"); m_vao = new VertexArray; - m_vao->addBuffer(&vboPositions[0], vboPositions.size() * sizeof(float)); + //Positions + ss >> currSize; + pos = (float*)&modelData[currPos]; + posBuffSize = currSize; + m_vao->addBuffer(&modelData[currPos], currSize); m_vao->pushFloat(3); m_vao->finishBufferLayout(); - m_vao->addBuffer(&vboTexCoords[0], vboTexCoords.size() * sizeof(float)); + currPos += currSize; + //Texture coordinates + ss >> currSize; + m_vao->addBuffer(&modelData[currPos], currSize); m_vao->pushFloat(2); m_vao->finishBufferLayout(); - m_vao->addBuffer(&vboNormals[0], vboNormals.size() * sizeof(float)); + currPos += currSize; + //Normals + ss >> currSize; + m_vao->addBuffer(&modelData[currPos], currSize); m_vao->pushFloat(3); m_vao->finishBufferLayout(); - m_vao->addBuffer(&vboTangents[0], vboTangents.size() * sizeof(float)); + currPos += currSize; + //Tangents + ss >> currSize; + m_vao->addBuffer(&modelData[currPos], currSize); m_vao->pushFloat(3); m_vao->finishBufferLayout(); - m_vao->addBuffer(&vboMaterialIndices[0], vboMaterialIndices.size() * sizeof(int)); + currPos += currSize; + //Material indices + ss >> currSize; + m_vao->addBuffer(&modelData[currPos], currSize); m_vao->pushInt(1); m_vao->finishBufferLayout(); - m_ib = new IndexBuffer(&vboIndices[0], vboIndices.size()); + currPos += currSize; + //Vertex indices + ss >> currSize; + indices = (unsigned int*)&modelData[currPos]; + indicesCount = currSize; + m_ib = new IndexBuffer(&modelData[currPos], currSize); if (physicsConvex) - Application::getApp()->getPhysicsEngine()->addConvexMesh(this, vboPositions); + Application::getApp()->getPhysicsEngine()->addConvexMesh(this, pos, posBuffSize); else if(physicsTriangle) - Application::getApp()->getPhysicsEngine()->addTriangleMesh(this, vboPositions, vboIndices); + Application::getApp()->getPhysicsEngine()->addTriangleMesh(this, pos, posBuffSize, indices, indicesCount); } - void Model::parseMaterials(std::unordered_map& mats, std::vector& mtl) { - std::string currMat; - size_t position = 0; - while (true) { - size_t nextLine = std::search(mtl.begin() + position, mtl.end(), m_newLine, m_newLine + std::strlen(m_newLine)) - (mtl.begin() + position); - if (position + nextLine >= mtl.size()) - break; - std::vector line(&mtl[position], &mtl[position + nextLine]); - position += nextLine + 1; - std::stringstream ss(std::string(&line[0], line.size())); - std::string firstWord; - ss >> firstWord; + void Model::createMaterials(const std::string& mats, AModel* model) { + std::stringstream ss(mats); + std::string temp; + std::getline(ss, temp); + unsigned int matCount = std::stoi(temp); + if (matCount > 32) + NFError("Model exceedes 32 material limit!"); - if (std::strcmp(&firstWord[0], "newmtl") == 0) { - std::string matName; - ss >> matName; - currMat = matName; - mats[currMat] = new TempMaterial; - } - else if (std::strcmp(&firstWord[0], "Kd") == 0) { - float r = 0.0f, g = 0.0f, b = 0.0f; - ss >> r >> g >> b; - mats[currMat]->diffuseColor = Vec3(r, g, b); - } - else if (std::strcmp(&firstWord[0], "map_Kd") == 0) { - std::string texName; - ss >> texName; - mats[currMat]->diffuseTextureName = texName; - } - else if (std::strcmp(&firstWord[0], "map_Ks") == 0) { - std::string texName; - ss >> texName; - mats[currMat]->specularTextureName = texName; - } - else if (std::strcmp(&firstWord[0], "map_Bump") == 0) { - std::string texName; - ss >> texName; - mats[currMat]->normalTextureName = texName; - } - else if (std::strcmp(&firstWord[0], "Ns") == 0) { - float s = 0.0f; - ss >> s; - mats[currMat]->shininess = s; - } + for (unsigned int i = 0; i < matCount; i++) { + Material curr; + + unsigned int texIndex; + + ss >> texIndex; + if (texIndex != 0) + curr.diffuse = new Texture(model->neededTextures[texIndex - 1]); + else + curr.diffuse = nullptr; + ss >> texIndex; + if (texIndex != 0) + curr.specular = new Texture(model->neededTextures[texIndex - 1], true); + else + curr.specular = nullptr; + ss >> texIndex; + if (texIndex != 0) + curr.normal = new Texture(model->neededTextures[texIndex - 1], true); + else + curr.normal = nullptr; + + ss >> curr.diffuseColor.x >> curr.diffuseColor.y >> curr.diffuseColor.z >> curr.shininess; + + m_materials.push_back(curr); } } @@ -320,7 +132,7 @@ namespace nf { for (unsigned int i = 0; i < m_materials.size(); i++) { std::string currMatSuffix = std::to_string(i) + (std::string)"]"; Texture* diff; - if ((diff = std::get<0>(m_materials[i])) != nullptr) { + if ((diff = m_materials[i].diffuse) != nullptr) { shader->setUniform(m_hasDiffString + currMatSuffix, true); diff->bind(texSlot); shader->setUniform(m_diffString + currMatSuffix, texSlot); @@ -328,11 +140,11 @@ namespace nf { } else { shader->setUniform(m_hasDiffString + currMatSuffix, false); - glm::vec3 color(std::get<3>(m_materials[i]), std::get<4>(m_materials[i]), std::get<5>(m_materials[i])); + glm::vec3 color(m_materials[i].diffuseColor.x, m_materials[i].diffuseColor.y, m_materials[i].diffuseColor.z); shader->setUniform(m_diffColorString + currMatSuffix, color); } Texture* spec; - if ((spec = std::get<1>(m_materials[i])) != nullptr) { + if ((spec = m_materials[i].specular) != nullptr) { shader->setUniform(m_hasSpecString + currMatSuffix, true); spec->bind(texSlot); shader->setUniform(m_specString + currMatSuffix, texSlot); @@ -341,7 +153,7 @@ namespace nf { else shader->setUniform(m_hasSpecString + currMatSuffix, false); Texture* norm; - if ((norm = std::get<2>(m_materials[i])) != nullptr) { + if ((norm = m_materials[i].normal) != nullptr) { shader->setUniform(m_hasNormString + currMatSuffix, true); norm->bind(texSlot); shader->setUniform(m_normString + currMatSuffix, texSlot); @@ -349,7 +161,7 @@ namespace nf { } else shader->setUniform(m_hasNormString + currMatSuffix, false); - shader->setUniform(m_specPowerString + currMatSuffix, std::get<6>(m_materials[i])); + shader->setUniform(m_specPowerString + currMatSuffix, m_materials[i].shininess); } } @@ -360,11 +172,11 @@ namespace nf { Model::~Model() { for (unsigned int i = 0; i < m_materials.size(); i++) { Texture* curr; - if ((curr = std::get<0>(m_materials[i])) != nullptr) + if ((curr = m_materials[i].diffuse) != nullptr) Application::getApp()->getCurrentState()->m_texturesToDelete.insert(curr); - if ((curr = std::get<1>(m_materials[i])) != nullptr) + if ((curr = m_materials[i].specular) != nullptr) Application::getApp()->getCurrentState()->m_texturesToDelete.insert(curr); - if ((curr = std::get<2>(m_materials[i])) != nullptr) + if ((curr = m_materials[i].normal) != nullptr) Application::getApp()->getCurrentState()->m_texturesToDelete.insert(curr); } } diff --git a/NothinFancy/src/Renderer/Texture.cpp b/NothinFancy/src/Renderer/Texture.cpp index 2cbeab8..1e47ec4 100644 --- a/NothinFancy/src/Renderer/Texture.cpp +++ b/NothinFancy/src/Renderer/Texture.cpp @@ -1,6 +1,8 @@ #include "nf/Texture.h" #include "GL/glew.h" +#define STB_IMAGE_IMPLEMENTATION +#include "stb_image.h" #include "nf/Assets.h" #include "nf/Utility.h" @@ -12,14 +14,18 @@ namespace nf { m_x(0), m_y(0) { - //Load dimensions and channels from cooked data int nChannels; + stbi_set_flip_vertically_on_load(true); + unsigned char* texture = stbi_load_from_memory((unsigned char*)tex->data, (unsigned int)tex->size, &m_x, &m_y, &nChannels, 0); + if (!texture) + NFError("Texture failed to load from memory!"); glGenTextures(1, &m_id); glBindTexture(GL_TEXTURE_2D, m_id); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, linear ? GL_RGBA : GL_SRGB_ALPHA, m_x, m_y, 0, nChannels == 3 ? GL_RGB : GL_RGBA, GL_UNSIGNED_BYTE, tex->data); + glTexImage2D(GL_TEXTURE_2D, 0, linear ? GL_RGBA : GL_SRGB_ALPHA, m_x, m_y, 0, nChannels == 3 ? GL_RGB : GL_RGBA, GL_UNSIGNED_BYTE, texture); glGenerateMipmap(GL_TEXTURE_2D); + stbi_image_free(texture); m_isBase = tex->isBaseAsset; tex->alreadyLoaded = true; tex->loadedTexture = this; diff --git a/NothinFancy/src/Utility.cpp b/NothinFancy/src/Utility.cpp index b398da7..d68b10b 100644 --- a/NothinFancy/src/Utility.cpp +++ b/NothinFancy/src/Utility.cpp @@ -160,33 +160,30 @@ namespace nf { out.close(); } - std::string readFile(const std::string& filename, bool compressed) { + bool readFile(const std::string& filename, std::string& out, bool assetPack) { if (!s_dHandle) CreateDecompressor(COMPRESS_ALGORITHM_XPRESS_HUFF, NULL, &s_dHandle); std::ifstream in; in.open(filename, std::ios::binary); if (!in) - NFError("File \"" + (std::string)filename + (std::string)"\" could not be read!"); + return false; std::stringstream ss; ss << in.rdbuf(); - std::string read(ss.str()); + out = ss.str(); - if (compressed) { + if (assetPack) { size_t decompSize; - Decompress(s_dHandle, &read[0], read.size(), NULL, 0, &decompSize); + Decompress(s_dHandle, &out[0], out.size(), NULL, 0, &decompSize); char* buff = new char[decompSize]; - Decompress(s_dHandle, &read[0], read.size(), buff, decompSize, &decompSize); - read = std::string(buff, decompSize); + Decompress(s_dHandle, &out[0], out.size(), buff, decompSize, &decompSize); + out = std::string(buff, decompSize); delete[] buff; - } - if (read.size() > 4 && read.substr(0, 4) == "NFEF") { - read = read.substr(4); - for (unsigned int i = 0; i < read.size(); i++) - read[i] = read[i] - 100; + for (unsigned int i = 0; i < out.size(); i++) + out[i] = out[i] - 100; } - return read; + return true; } } diff --git a/NothinFancy/src/include/nf/Assets.h b/NothinFancy/src/include/nf/Assets.h index f8e85d0..999544b 100644 --- a/NothinFancy/src/include/nf/Assets.h +++ b/NothinFancy/src/include/nf/Assets.h @@ -23,7 +23,7 @@ namespace nf { struct AModel : Asset { Model* loadedModel = nullptr; - std::unordered_map neededTextures; + std::vector neededTextures; ~AModel() override; }; diff --git a/NothinFancy/src/include/nf/Model.h b/NothinFancy/src/include/nf/Model.h index 91b6cc8..77a835b 100644 --- a/NothinFancy/src/include/nf/Model.h +++ b/NothinFancy/src/include/nf/Model.h @@ -19,34 +19,18 @@ namespace nf { ~Model(); private: - struct TempMaterial { - std::vector outVB; - std::vector unindexedVB; - std::vector vbIndices; - std::vector outTC; - std::vector unindexedTC; - std::vector tcIndices; - std::vector outVN; - std::vector unindexedVN; - std::vector vnIndices; - std::vector unindexedTan; - std::vector outTan; - std::vector outIB; - unsigned int ibCount = 0; - - std::string diffuseTextureName; + struct Material { + Texture* diffuse; + Texture* specular; + Texture* normal; Vec3 diffuseColor; - std::string specularTextureName; - std::string normalTextureName; float shininess = 1.0f; }; - void parseMaterials(std::unordered_map& mats, std::vector& mtl); + void createMaterials(const std::string& mats, AModel* model); bool m_base; - std::vector> m_materials; - const char* m_newMtl; - const char* m_newLine; + std::vector m_materials; const std::string m_hasDiffString = "hasDiffuseTex["; const std::string m_diffString = "diffuseTexture["; const std::string m_diffColorString = "diffuseColor["; diff --git a/NothinFancy/src/include/nf/PhysicsEngine.h b/NothinFancy/src/include/nf/PhysicsEngine.h index 26cf3e9..1d429f3 100644 --- a/NothinFancy/src/include/nf/PhysicsEngine.h +++ b/NothinFancy/src/include/nf/PhysicsEngine.h @@ -21,8 +21,8 @@ namespace nf { void setActorVelocity(Entity* ent, const Vec3& vel); void setActorMass(Entity* ent, float mass); void update(float dt); - void addConvexMesh(Model* model, std::vector& vertices); - void addTriangleMesh(Model* model, std::vector& vertices, std::vector& indices); + void addConvexMesh(Model* model, const float* vertices, unsigned int buffSize); + void addTriangleMesh(Model* model, const float* vertices, unsigned int vertBuffSize, const unsigned int* indices, unsigned int indicesCount); void addActor(Entity* entity); void closeScene(); diff --git a/NothinFancy/src/include/nf/Utility.h b/NothinFancy/src/include/nf/Utility.h index 46076ae..ec359da 100644 --- a/NothinFancy/src/include/nf/Utility.h +++ b/NothinFancy/src/include/nf/Utility.h @@ -428,13 +428,12 @@ std::exit(-1);} /** * @brief Reads a file's bytes into an std::string * @param filename Path and name of file to be read, including extensions; Relative or absolute - * @param compressed Internal use only as of now - * @return An std::string containing the specified file's bytes + * @param out The output std::string to receive the file contents + * @param assetPack Internal use only as of now + * @return If the file was successfully read or not * * This function automatically detects whether or not the target file is encrypted * and decrypts it if it is. - * - * @todo If files aren't found, the engine errors. Change this. */ - std::string readFile(const std::string& filename, bool compressed = false); + bool readFile(const std::string& filename, std::string& out, bool assetPack = false); } \ No newline at end of file