Added the materials system; Any model can have any number of materials with different textures and properties
This commit is contained in:
1 parent
70318b28fd
commit
39e0c8e808
37 files changed
+1616
-1327
No files matched your search
+48
-13
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
Reference in new issue
Block a user