Finished reworking asset builder; Models are now cooked when built

This commit is contained in:
grayson committed 2021-12-14 03:04:56 -06:00
1 parent cc0316ff80
commit 7a93befa14
20 files changed
+291 -475

No files matched your search

@@ -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);
}
File diff suppressed because it is too large. Load diff
+73 -63
View File
@@ -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<std::string, ACubemap*> cubemaps;
std::unordered_map<std::string, AButton*> 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;
+1 -3
View File
@@ -41,17 +41,15 @@ namespace nf {
std::vector<CMFace> 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);
+8 -8
View File
@@ -171,11 +171,11 @@ namespace nf {
}
}
void PhysicsEngine::addConvexMesh(Model* model, std::vector<float>& 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<float>& vertices, std::vector<unsigned int>& 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))
+81 -269
View File
@@ -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<char> 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<char> mtl(&file[mtlPos], &file[0] + file.size());
std::unordered_map<std::string, TempMaterial*> 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<char> obj(&file[0], &file[mtlPos]);
std::vector<float> 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<char> 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<float> vboPositions;
std::vector<float> vboTexCoords;
std::vector<float> vboNormals;
std::vector<float> vboTangents;
std::vector<int> vboMaterialIndices;
std::vector<unsigned int> vboIndices;
int matCount = 0;
for (auto& m : mats) {
std::string curr = m.first;
std::map<Vertex, unsigned int> 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<std::string, TempMaterial*>& mats, std::vector<char>& 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<char> 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);
}
}
+8 -2
View File
@@ -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;
+10 -13
View File
@@ -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;
}
}
+1 -1
View File
@@ -23,7 +23,7 @@ namespace nf {
struct AModel : Asset {
Model* loadedModel = nullptr;
std::unordered_map<std::string, ATexture*> neededTextures;
std::vector<ATexture*> neededTextures;
~AModel() override;
};
+6 -22
View File
@@ -19,34 +19,18 @@ namespace nf {
~Model();
private:
struct TempMaterial {
std::vector<float> outVB;
std::vector<float> unindexedVB;
std::vector<unsigned int> vbIndices;
std::vector<float> outTC;
std::vector<float> unindexedTC;
std::vector<unsigned int> tcIndices;
std::vector<float> outVN;
std::vector<float> unindexedVN;
std::vector<unsigned int> vnIndices;
std::vector<float> unindexedTan;
std::vector<float> outTan;
std::vector<unsigned int> 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<std::string, TempMaterial*>& mats, std::vector<char>& mtl);
void createMaterials(const std::string& mats, AModel* model);
bool m_base;
std::vector<std::tuple<Texture*, Texture*, Texture*, float, float, float, float>> m_materials;
const char* m_newMtl;
const char* m_newLine;
std::vector<Material> m_materials;
const std::string m_hasDiffString = "hasDiffuseTex[";
const std::string m_diffString = "diffuseTexture[";
const std::string m_diffColorString = "diffuseColor[";
+2 -2
View File
@@ -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<float>& vertices);
void addTriangleMesh(Model* model, std::vector<float>& vertices, std::vector<unsigned int>& 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();
+4 -5
View File
@@ -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);
}