Added the materials system; Any model can have any number of materials with different textures and properties

This commit is contained in:
grayson committed 2021-09-09 23:18:42 -05:00
1 parent 70318b28fd
commit 39e0c8e808
37 files changed
+1616 -1327

No files matched your search

+48 -13
View File
@@ -1,5 +1,7 @@
#include "Assets.h"
#include <sstream>
#include "Application.h"
#include "Model.h"
#include "Utility.h"
@@ -9,11 +11,11 @@ namespace nf {
delete[] data;
}
AModel::~AModel() {
ATexture::~ATexture() {
}
ATexture::~ATexture() {
AModel::~AModel() {
}
@@ -41,6 +43,7 @@ namespace nf {
void AssetPack::load(const char* packName) {
std::string path = "assets/" + (std::string)packName;
std::string packContents = readFile(path);
std::string packContentsOBJ = packContents;
std::unordered_map<std::string, ACubemap*> cubemaps;
unsigned int cubemapCount = 0;
while (packContents.size()) {
@@ -63,18 +66,8 @@ namespace nf {
}
size_t assetSize = assetContents.size();
if (extension == "obj") {
AModel* geometry = new AModel;
geometry->data = new char[assetSize + 1];
std::memcpy(geometry->data, &assetContents[0], assetSize);
geometry->data[assetSize] = '\0';
geometry->alreadyLoaded = false;
geometry->loadedModel = nullptr;
if (packName == "base.nfpack")
geometry->isBaseAsset = true;
m_assets[assetName] = geometry;
if (extension == "obj")
continue;
}
if (extension == "png") {
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('_'));
@@ -156,6 +149,48 @@ namespace nf {
}
if (cubemapCount % 6 != 0)
Error("Could not find full cubemap in pack \"" + (std::string)packName + (std::string)"\"!");
while (packContentsOBJ.size()) {
unsigned int startingPos = packContentsOBJ.find_first_of("#NFASSET ") + 9;
packContentsOBJ = packContentsOBJ.substr(9);
unsigned int endAssetNamePos = packContentsOBJ.find_first_of('\n');
std::string assetName = packContentsOBJ.substr(0, endAssetNamePos);
packContentsOBJ = packContentsOBJ.substr(endAssetNamePos + 1);
unsigned int extensionPos = assetName.find_first_of('.');
std::string extension = assetName.substr(extensionPos + 1);
std::string assetContents;
unsigned int nextAssetPos = packContentsOBJ.find("#NFASSET ");
if (nextAssetPos != std::string::npos) {
assetContents = packContentsOBJ.substr(0, nextAssetPos - 1);
packContentsOBJ = packContentsOBJ.substr(nextAssetPos);
}
else {
assetContents = packContentsOBJ;
packContentsOBJ = "";
}
size_t assetSize = assetContents.size();
if (extension == "obj") {
AModel* model = new AModel;
std::string textures = assetContents.substr(0, assetContents.find("\n"));
if (textures != "none") {
std::stringstream ss(textures);
std::string curr;
while (ss >> curr) {
model->neededTextures[curr] = (ATexture*)m_assets[curr];
}
}
assetContents = assetContents.substr(assetContents.find("\n") + 1);
model->data = new char[assetSize + 1];
std::memcpy(model->data, &assetContents[0], assetSize);
model->data[assetSize] = '\0';
if (packName == "base.nfpack")
model->isBaseAsset = true;
m_assets[assetName] = model;
continue;
}
}
if (packName != "base.nfpack")
Application::getApp()->getCurrentState()->m_nfObjects.push_back(this);
}
+1 -1
View File
@@ -9,7 +9,7 @@ namespace nf {
Log("Intro onEnter!");
m_logoTex.create(BaseAssets::logo, Vec2(0.0, 0.0));
m_logoTex.centered(true, true);
m_text.create("(C) Grayson Riffe 2021", Vec2(0.01, 0.025), Vec3(0.8));
m_text.create("(c) Grayson Riffe 2021", Vec2(0.01, 0.025), Vec3(0.8));
m_text.setScale(0.6);
m_start = std::chrono::steady_clock::now();
}
+8 -26
View File
@@ -17,26 +17,14 @@ namespace nf {
}
void Entity::create(Asset* modelAsset, Asset* textureAsset) {
void Entity::create(Asset* modelAsset) {
m_constructed = true;
AModel& model = *(AModel*)modelAsset;
//TODO: Change this when doing materials
if (model.alreadyLoaded && textureAsset == nullptr) {
if (model.alreadyLoaded) {
m_model = model.loadedModel;
}
else {
if (!textureAsset)
Error("No texture given to Entity create function on new model load!");
ATexture& texture = *(ATexture*)textureAsset;
std::string obj = model.data;
m_model = new Model;
std::vector<float> vb;
std::vector<unsigned int> ib;
size_t ibCount = 0;
std::vector<float> tc;
std::vector<float> vn;
parseOBJ(obj, vb, ib, ibCount, tc, vn);
m_model->create(&vb[0], vb.size() * sizeof(float), &ib[0], ibCount, &vn[0], vn.size() * sizeof(float), &tc[0], tc.size() * sizeof(float), &texture);
m_model = new Model(&model);
model.alreadyLoaded = true;
model.loadedModel = m_model;
}
@@ -76,10 +64,10 @@ namespace nf {
m_scale = scale;
}
void Entity::bind(Shader* shader) {
m_model->bind();
void Entity::render(Shader* shader) {
shader->bind();
setModelMatrix(shader);
m_model->render(shader);
}
Model* Entity::getModel() const {
@@ -101,15 +89,9 @@ namespace nf {
if(m_model && !m_model->isBaseAsset())
delete m_model;
m_model = nullptr;
m_position.x = 0.0;
m_position.y = 0.0;
m_position.z = 0.0;
m_rotation.x = 0.0;
m_rotation.y = 0.0;
m_rotation.z = 0.0;
m_scale.x = 1.0;
m_scale.y = 1.0;
m_scale.z = 1.0;
m_position = Vec3(0.0);
m_rotation = Vec3(0.0);
m_scale = Vec3(1.0);
}
Entity::~Entity() {
+2 -2
View File
@@ -12,12 +12,12 @@ namespace nf {
}
void Light::create(const Vec3& position, const Vec3& color, float strength, Type type) {
void Light::create(const Vec3& position, const Vec3& color, double strength, Type type) {
m_constructed = true;
m_position = position;
m_color = color;
m_type = type;
m_strength = strength;
m_strength = (float)strength;
Application::getApp()->getCurrentState()->m_nfObjects.push_back(this);
}
+264 -27
View File
@@ -1,49 +1,284 @@
#include "Model.h"
#include <map>
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "GL/glew.h"
#include "Utility.h"
#include "Texture.h"
#include "Shader.h"
#include "Utility.h"
namespace nf {
Model::Model() :
m_base(false),
m_texture(nullptr)
{
}
void Model::create(const void* vertexBufferData, const size_t vertexBufferSize, const void* indexBufferData, size_t indexBufferCount, const void* normalsBufferData, size_t normalsBufferSize, const void* textureCoordinatesBufferData, size_t textureCoordinatesBufferSize, ATexture* texture) {
m_vao = new VertexArray;
m_vao->addBuffer(vertexBufferData, vertexBufferSize);
Material::Material(const void* vb, const size_t vbSize, const void* tc, const size_t tcSize, const void* vn, const size_t vnSize, const void* ib, const unsigned int ibCount, ATexture* diffTex, Vec3& diffColor, ATexture* specTex, float shininess) {
m_vao = new VertexArray();
m_vao->addBuffer(vb, vbSize);
m_vao->push<float>(3);
m_vao->finishBufferLayout();
m_vao->addBuffer(textureCoordinatesBufferData, textureCoordinatesBufferSize);
m_vao->addBuffer(tc, tcSize);
m_vao->push<float>(2);
m_vao->finishBufferLayout();
m_vao->addBuffer(normalsBufferData, normalsBufferSize);
m_vao->addBuffer(vn, vnSize);
m_vao->push<float>(3);
m_vao->finishBufferLayout();
if (texture->alreadyLoaded) {
m_texture = texture->loadedTexture;
m_ib = new IndexBuffer(ib, ibCount);
if (diffTex) {
m_hasDiffuse = true;
m_diffuseTexture = new Texture(diffTex);
}
else {
m_texture = new Texture;
m_texture->create(texture);
texture->alreadyLoaded = true;
texture->loadedTexture = m_texture;
m_diffColor = diffColor;
if (specTex) {
m_hasSpecular = true;
m_specularTexture = new Texture(specTex);
}
m_ib = new IndexBuffer(indexBufferData, indexBufferCount);
m_shininess = shininess;
}
void Model::bind() {
if (m_vao == nullptr)
Error("Tried to bind uninitialized model!");
void Material::render(Shader* shader) {
m_vao->bind();
if (m_texture)
m_texture->bind();
m_ib->bind();
if (m_hasDiffuse) {
shader->setUniform("material.hasDiffuseTex", true);
m_diffuseTexture->bind();
}
else {
shader->setUniform("material.hasDiffuseTex", false);
glm::vec3 color(m_diffColor.x, m_diffColor.y, m_diffColor.z);
shader->setUniform("material.diffuseColor", color);
}
if (m_hasSpecular) {
shader->setUniform("material.hasSpecTex", true);
m_specularTexture->bind(1);
shader->setUniform("material.specularTexture", 1);
}
else
shader->setUniform("material.hasSpecTex", false);
shader->setUniform("material.specPower", m_shininess);
glDrawElements(GL_TRIANGLES, m_ib->getCount(), GL_UNSIGNED_INT, nullptr);
}
Material::~Material() {
delete m_diffuseTexture;
delete m_specularTexture;
}
Model::Model(AModel* model) :
m_base(false)
{
std::string obj = model->data;
unsigned int startMtlPos = obj.find("newmtl");
if (startMtlPos == std::string::npos)
Error("No materials found in model!");
std::string mtl = obj.substr(startMtlPos);
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<unsigned int> outIB;
unsigned int ibCount = 0;
std::string diffuseTextureName;
Vec3 diffuseColor;
std::string specularTextureName;
float shininess = 1.0f;
};
std::unordered_map<std::string, TempMaterial*> mats;
std::string currMat;
while (true) {
char line[500];
int result = sscanf_s(mtl.c_str(), "\n%s", line, (unsigned)_countof(line));
if (result == EOF)
break;
if (std::strcmp(line, "newmtl") == 0) {
char matName[100];
sscanf_s(mtl.c_str(), "\nnewmtl %s\n", matName, (unsigned)_countof(matName));
currMat = matName;
mats[currMat] = new TempMaterial;
}
else if (std::strcmp(line, "Kd") == 0) {
float r = 0.0, g = 0.0, b = 0.0;
sscanf_s(mtl.c_str(), "\nKd %f %f %f\n", &r, &g, &b);
mats[currMat]->diffuseColor = Vec3(r, g, b);
}
else if (std::strcmp(line, "map_Kd") == 0) {
char texName[100];
sscanf_s(mtl.c_str(), "\nmap_Kd %s\n", texName, (unsigned)_countof(texName));
mats[currMat]->diffuseTextureName = (std::string)texName;
}
else if (std::strcmp(line, "map_Ks") == 0) {
char texName[100];
sscanf_s(mtl.c_str(), "\nmap_Ks %s\n", texName, (unsigned)_countof(texName));
mats[currMat]->specularTextureName = (std::string)texName;
}
else if (std::strcmp(line, "Ns") == 0) {
float s = 0.0;
sscanf_s(mtl.c_str(), "\nNs %f\n", &s);
mats[currMat]->shininess = s;
}
unsigned int pos = mtl.find(line) + strlen(line);
mtl = mtl.substr(pos);
}
std::string file = obj.substr(0, startMtlPos);
std::vector<float> vbRaw, tcRaw, vnRaw;
std::string usingMat;
bool tcPresent = false, vnPresent = false;
while (true) {
char line[500];
int remove = 0;
int result = sscanf_s(file.c_str(), "\n%s", line, (unsigned)_countof(line));
if (result == EOF)
break;
if (std::strcmp(line, "v") == 0) {
float x = 0.0, y = 0.0, z = 0.0;
sscanf_s(file.c_str(), "\nv %f %f %f\n", &x, &y, &z);
remove = 28;
vbRaw.push_back(x);
vbRaw.push_back(y);
vbRaw.push_back(z);
}
else if (std::strcmp(line, "vt") == 0) {
tcPresent = true;
float u = 0.0, v = 0.0;
sscanf_s(file.c_str(), "\nvt %f %f\n", &u, &v);
remove = 18;
tcRaw.push_back(u);
tcRaw.push_back(v);
}
else if (std::strcmp(line, "vn") == 0) {
vnPresent = true;
float x = 0.0, y = 0.0, z = 0.0;
sscanf_s(file.c_str(), "\nvn %f %f %f\n", &x, &y, &z);
remove = 20;
vnRaw.push_back(x);
vnRaw.push_back(y);
vnRaw.push_back(z);
}
else if (std::strcmp(line, "usemtl") == 0) {
char matName[100];
sscanf_s(file.c_str(), "\nusemtl %s\n", matName, (unsigned)_countof(matName));
usingMat = matName;
remove = 5;
}
else if (std::strcmp(line, "f") == 0) {
unsigned int vertexIndex[3], uvIndex[3], vnIndex[3];
sscanf_s(file.c_str(), "\nf %d/%d/%d %d/%d/%d %d/%d/%d\n", &vertexIndex[0], &uvIndex[0], &vnIndex[0], &vertexIndex[1], &uvIndex[1], &vnIndex[1], &vertexIndex[2], &uvIndex[2], &vnIndex[2]);
remove = 15;
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]);
}
unsigned int pos = file.find(line) + strlen(line) + remove;
file = file.substr(pos);
}
if (!tcPresent)
Error("No texture coordinates found in model!");
if (!vnPresent)
Error("No normals found in model!");
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);
}
}
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;
}
};
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);
unsigned int index = (mats[curr]->outVB.size() / 3) - 1;
mats[curr]->outIB.push_back(index);
vertexMap[currVertex] = index;
mats[curr]->ibCount++;
}
}
}
for (auto& m : mats) {
TempMaterial& curr = *m.second;
ATexture* diff = nullptr;
if (curr.diffuseTextureName.size())
diff = model->neededTextures[curr.diffuseTextureName];
ATexture* spec = nullptr;
if (curr.specularTextureName.size())
spec = model->neededTextures[curr.specularTextureName];
m_materials.push_back(new Material(&curr.outVB[0], curr.outVB.size() * sizeof(float), &curr.outTC[0], curr.outTC.size() * sizeof(float), &curr.outVN[0], curr.outVN.size() * sizeof(float), &curr.outIB[0], curr.ibCount, diff, curr.diffuseColor, spec, curr.shininess));
delete m.second;
}
}
void Model::render(Shader* shader) {
for (Material* curr : m_materials) {
curr->render(shader);
}
}
void Model::setBaseAsset(bool isBase) {
@@ -55,6 +290,8 @@ namespace nf {
}
Model::~Model() {
delete m_texture;
for (Material* curr : m_materials) {
delete curr;
}
}
}
@@ -136,9 +136,11 @@ namespace nf {
1.0, 1.0,
1.0, 0.0
};
glActiveTexture(GL_TEXTURE10);
glBindTexture(GL_TEXTURE_2D, c.texID);
m_vao->setBufferData(0, vb, sizeof(vb));
m_vao->setBufferData(1, tc, sizeof(tc));
shader->setUniform("text", 10);
glDrawArrays(GL_TRIANGLES, 0, 6);
currX += (c.advance >> 6) * scale * m_scale;
}
@@ -25,8 +25,7 @@ namespace nf {
m_texture = tex->loadedTexture;
}
else {
m_texture = new Texture;
m_texture->create(tex);
m_texture = new Texture(tex);
}
m_vao = new VertexArray;
+5 -6
View File
@@ -155,15 +155,12 @@ namespace nf {
m_entityShader->setUniform("proj", proj);
for (Entity* draw : m_lGame) {
Entity& curr = *draw;
curr.bind(m_entityShader);
//TODO: Clean this up a bit
m_entityShader->setUniform("numberOfLights", (int)m_lights.size() + 1);
for (unsigned int i = 0; i < m_lights.size(); i++) {
m_lights[i]->bind(m_entityShader, i);
}
//TODO: Bind and draw every material here
m_entityShader->setUniform("material.shininess", 1.0f);
glDrawElements(GL_TRIANGLES, curr.getModel()->getIndexCount(), GL_UNSIGNED_INT, nullptr);
curr.render(m_entityShader);
}
m_lGame.clear();
m_lights.clear();
@@ -203,7 +200,9 @@ namespace nf {
m_loadingText.setOpacity(opacity);
m_loadingText.render(m_textShader, m_app->getConfig().width, m_app->getConfig().height);
}
opacity -= 0.8 * dT;
if (dT > 1.0 / 60.0)
dT = 1.0 / 60.0;
opacity -= 2.5 * dT;
if (opacity <= 0.0) {
m_fadeIn = false;
m_fadeOutComplete = false;
@@ -221,7 +220,7 @@ namespace nf {
m_loadingText.setOpacity(opacity);
m_loadingText.render(m_textShader, m_app->getConfig().width, m_app->getConfig().height);
}
opacity += 1.2 * dT;
opacity += 3.0 * dT;
if (opacity >= 1.0) {
m_fadeIn = false;
m_fadeOutComplete = true;
+4 -6
View File
@@ -8,16 +8,12 @@
#include "Utility.h"
namespace nf {
Texture::Texture() :
Texture::Texture(ATexture* tex) :
m_isBase(false),
m_id(0),
m_x(0),
m_y(0)
{
}
void Texture::create(ATexture* tex) {
int nChannels;
stbi_set_flip_vertically_on_load(true);
unsigned char* texture = stbi_load_from_memory((unsigned char*)tex->data, tex->size, &m_x, &m_y, &nChannels, 0);
@@ -33,8 +29,10 @@ namespace nf {
m_isBase = tex->isBaseAsset;
}
void Texture::bind() {
void Texture::bind(unsigned int slot) {
glActiveTexture(GL_TEXTURE0 + slot);
glBindTexture(GL_TEXTURE_2D, m_id);
glActiveTexture(GL_TEXTURE0);
}
Vec2 Texture::getDimensions() {
-128
View File
@@ -3,7 +3,6 @@
#include <iostream>
#include <sstream>
#include <fstream>
#include <map>
#include "glm/glm.hpp"
#include "Config.h"
@@ -110,133 +109,6 @@ namespace nf {
}
return read;
}
void parseOBJ(std::string& in, std::vector<float>& vbOut, std::vector<unsigned int>& ibOut, size_t& ibCountOut, std::vector<float>& tcOut, std::vector<float>& vnOut) {
std::string file = in;
std::vector<float> vbRaw, tcRaw, vnRaw;
std::vector<unsigned int> vertexIndices, uvIndices, vnIndices;
std::vector<float> tempVertices, tempTC, tempVN;
bool tcPresent = false, vnPresent = false;
while (true) {
char line[500];
int remove = 0;
int result = sscanf_s(file.c_str(), "\n%s", line, (unsigned)_countof(line));
if (result == EOF)
break;
if (std::strcmp(line, "v") == 0) {
float x = 0.0, y = 0.0, z = 0.0;
sscanf_s(file.c_str(), "\nv %f %f %f\n", &x, &y, &z);
remove = 28;
tempVertices.push_back(x);
tempVertices.push_back(y);
tempVertices.push_back(z);
}
else if (std::strcmp(line, "vt") == 0) {
tcPresent = true;
float u = 0.0, v = 0.0;
sscanf_s(file.c_str(), "\nvt %f %f\n", &u, &v);
remove = 18;
tempTC.push_back(u);
tempTC.push_back(v);
}
if (std::strcmp(line, "vn") == 0) {
vnPresent = true;
float x = 0.0, y = 0.0, z = 0.0;
sscanf_s(file.c_str(), "\nvn %f %f %f\n", &x, &y, &z);
remove = 20;
tempVN.push_back(x);
tempVN.push_back(y);
tempVN.push_back(z);
}
else if (std::strcmp(line, "f") == 0) {
unsigned int vertexIndex[3], uvIndex[3], vnIndex[3];
sscanf_s(file.c_str(), "\nf %d/%d/%d %d/%d/%d %d/%d/%d\n", &vertexIndex[0], &uvIndex[0], &vnIndex[0], &vertexIndex[1], &uvIndex[1], &vnIndex[1], &vertexIndex[2], &uvIndex[2], &vnIndex[2]);
remove = 15;
vertexIndices.push_back(vertexIndex[0]);
vertexIndices.push_back(vertexIndex[1]);
vertexIndices.push_back(vertexIndex[2]);
uvIndices.push_back(uvIndex[0]);
uvIndices.push_back(uvIndex[1]);
uvIndices.push_back(uvIndex[2]);
vnIndices.push_back(vnIndex[0]);
vnIndices.push_back(vnIndex[1]);
vnIndices.push_back(vnIndex[2]);
}
unsigned int pos = file.find(line) + strlen(line) + remove;
file = file.substr(pos);
}
if (!tcPresent)
Error("No texture coordinates found in model!");
if (!vnPresent)
Error("No normals found in model!");
for (unsigned int i = 0; i < vertexIndices.size(); i++) {
unsigned int vertexIndex = vertexIndices[i];
unsigned int uvIndex = uvIndices[i];
unsigned int vnIndex = vnIndices[i];
float vertexX = tempVertices[(vertexIndex - 1) * 3];
float vertexY = tempVertices[(vertexIndex - 1) * 3 + 1];
float vertexZ = tempVertices[(vertexIndex - 1) * 3 + 2];
float vertexU = tempTC[(uvIndex - 1) * 2];
float vertexV = tempTC[(uvIndex - 1) * 2 + 1];
float vnX = tempVN[(vnIndex - 1) * 3];
float vnY = tempVN[(vnIndex - 1) * 3 + 1];
float vnZ = tempVN[(vnIndex - 1) * 3 + 2];
vbRaw.push_back(vertexX);
vbRaw.push_back(vertexY);
vbRaw.push_back(vertexZ);
tcRaw.push_back(vertexU);
tcRaw.push_back(vertexV);
vnRaw.push_back(vnX);
vnRaw.push_back(vnY);
vnRaw.push_back(vnZ);
}
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::map<Vertex, unsigned int> vertexMap;
for (unsigned int i = 0; i * 3 < vbRaw.size(); i++) {
Vertex curr = { vbRaw[(i * 3)], vbRaw[(i * 3) + 1], vbRaw[(i * 3) + 2], tcRaw[(i * 2)], tcRaw[(i * 2) + 1], vnRaw[(i * 3)], vnRaw[(i * 3) + 1], vnRaw[(i * 3) + 2] };
bool found = false;
found = vertexMap.find(curr) != vertexMap.end();
if (found) {
unsigned int index = vertexMap[curr];
ibOut.push_back(index);
ibCountOut++;
}
else {
vbOut.push_back(curr.x);
vbOut.push_back(curr.y);
vbOut.push_back(curr.z);
tcOut.push_back(curr.u);
tcOut.push_back(curr.v);
vnOut.push_back(curr.vnX);
vnOut.push_back(curr.vnY);
vnOut.push_back(curr.vnZ);
unsigned int index = (vbOut.size() / 3) - 1;
ibOut.push_back(index);
vertexMap[curr] = index;
ibCountOut++;
}
}
}
}
//Nvidia Optimius support
+9 -6
View File
@@ -1,5 +1,6 @@
#pragma once
#include <unordered_map>
#include "NFObject.h"
namespace nf {
@@ -14,12 +15,6 @@ namespace nf {
virtual ~Asset();
};
struct AModel : Asset {
Model* loadedModel = nullptr;
~AModel() override;
};
struct ATexture : Asset {
size_t size = 0;
Texture* loadedTexture = nullptr;
@@ -27,6 +22,14 @@ namespace nf {
~ATexture() override;
};
struct AModel : Asset {
Model* loadedModel = nullptr;
std::unordered_map<std::string, ATexture*> neededTextures;
~AModel() override;
};
struct ACubemap : Asset {
char* frontData = nullptr;
size_t frontSize = 0;
+2 -2
View File
@@ -11,7 +11,7 @@ namespace nf {
public:
Entity();
void create(Asset* modelAsset, Asset* textureAsset = nullptr);
void create(Asset* modelAsset);
bool isConstructed();
void setPosition(double x, double y, double z);
@@ -22,7 +22,7 @@ namespace nf {
void setScale(double x, double y, double z);
void setScale(const Vec3& scale);
void bind(Shader* shader);
void render(Shader* shader);
Model* getModel() const;
void destroy() override;
+1 -1
View File
@@ -13,7 +13,7 @@ namespace nf {
};
Light();
void create(const Vec3& position, const Vec3& color, float strength = 1.0f, Type type = Type::POINT);
void create(const Vec3& position, const Vec3& color, double strength = 1.0, Type type = Type::POINT);
bool isConstructed();
void setPosition(const Vec3& position);
void setColor(const Vec3& color);
+22 -5
View File
@@ -1,17 +1,34 @@
#pragma once
#include "Drawable.h"
#include "Assets.h"
#include "Utility.h"
namespace nf {
class Drawable;
class Texture;
class Shader;
class Model : public Drawable {
class Material : public Drawable {
public:
Model();
Material(const void* vb, const size_t vbSize, const void* tc, const size_t tcSize, const void* vn, const size_t vnSize, const void* ib, const unsigned int ibCount, ATexture* diffTex, Vec3& diffColor, ATexture* specTex, float shininess);
void create(const void* vertexBufferData, const size_t vertexBufferSize, const void* indexBufferData, size_t indexBufferCount, const void* textureCoordinatesBufferData, size_t textureCoordinatesBufferSize, const void* normalsBufferData, size_t normalsBufferSize, ATexture* texture);
void bind() override;
void render(Shader* shader);
~Material();
private:
bool m_hasDiffuse = false;
Texture* m_diffuseTexture = nullptr;
Vec3 m_diffColor;
bool m_hasSpecular = false;
Texture* m_specularTexture = nullptr;
float m_shininess;
};
class Model {
public:
Model(AModel* model);
void render(Shader* shader);
void setBaseAsset(bool isBase);
bool isBaseAsset();
@@ -19,6 +36,6 @@ namespace nf {
~Model();
private:
bool m_base;
Texture* m_texture;
std::vector<Material*> m_materials;
};
}
+2 -3
View File
@@ -6,10 +6,9 @@ namespace nf {
class Texture {
public:
Texture();
Texture(ATexture* tex);
void create(ATexture* tex);
void bind();
void bind(unsigned int slot = 0);
Vec2 getDimensions();
bool isBaseAsset();
-3
View File
@@ -1,7 +1,6 @@
#pragma once
#include <chrono>
#include <string>
#include <vector>
#include <Windows.h>
namespace nf {
@@ -83,6 +82,4 @@ std::exit(-1);}
const wchar_t* toWide(const std::string& in);
void writeFile(const std::string& filename, const std::string& in, bool encrypted = false);
std::string readFile(const std::string& filename);
void parseOBJ(std::string& in, std::vector<float>& vbOut, std::vector<unsigned int>& ibOut, size_t& ibCountOut, std::vector<float>& tcOut, std::vector<float>& vnOut);
}