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

This commit is contained in:
Grayson Riffe (Laptop) 2021-09-09 22:49:49 -05:00
parent 70318b28fd
commit 39e0c8e808
37 changed files with 1616 additions and 1327 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 502 KiB

View File

@ -1,46 +0,0 @@
# Blender v2.93.3 OBJ File: ''
# www.blender.org
o Cube_Cube.001
v -1.000000 -1.000000 -1.000000
v -1.000000 1.000000 -1.000000
v 1.000000 -1.000000 -1.000000
v 1.000000 1.000000 -1.000000
v -1.000000 -1.000000 1.000000
v -1.000000 1.000000 1.000000
v 1.000000 -1.000000 1.000000
v 1.000000 1.000000 1.000000
vt 0.380883 0.000961
vt 0.630883 0.250961
vt 0.380883 0.250961
vt 0.875500 0.748039
vt 0.625500 0.498039
vt 0.875500 0.498039
vt 0.625500 0.748039
vt 0.375500 0.498039
vt 0.375500 0.748039
vt 0.125500 0.498039
vt 0.375500 0.248039
vt 0.625500 0.248039
vt 0.625500 0.998039
vt 0.630883 0.000961
vt 0.125500 0.748039
vt 0.375500 0.998039
vn 0.0000 0.0000 -1.0000
vn 1.0000 0.0000 0.0000
vn 0.0000 0.0000 1.0000
vn -1.0000 0.0000 0.0000
vn 0.0000 -1.0000 0.0000
vn 0.0000 1.0000 0.0000
s off
f 2/1/1 3/2/1 1/3/1
f 4/4/2 7/5/2 3/6/2
f 8/7/3 5/8/3 7/5/3
f 6/9/4 1/10/4 5/8/4
f 7/5/5 1/11/5 3/12/5
f 4/13/6 6/9/6 8/7/6
f 2/1/1 4/14/1 3/2/1
f 4/4/2 8/7/2 7/5/2
f 8/7/3 6/9/3 5/8/3
f 6/9/4 2/15/4 1/10/4
f 7/5/5 5/8/5 1/11/5
f 4/13/6 2/16/6 6/9/6

View File

@ -0,0 +1,14 @@
# Blender MTL File: 'None'
# Material Count: 1
newmtl Material.001
Ns 750.283502
Ka 1.000000 1.000000 1.000000
Kd 0.800000 0.800000 0.800000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.450000
d 1.000000
illum 2
map_Kd diff.png
map_Ks spec.png

View File

@ -0,0 +1,46 @@
# Blender v2.93.3 OBJ File: ''
# www.blender.org
mtllib spec.mtl
o Cube_Cube.001
v -1.000000 -1.000000 1.000000
v -1.000000 1.000000 1.000000
v -1.000000 -1.000000 -1.000000
v -1.000000 1.000000 -1.000000
v 1.000000 -1.000000 1.000000
v 1.000000 1.000000 1.000000
v 1.000000 -1.000000 -1.000000
v 1.000000 1.000000 -1.000000
vt -2.000000 -1.000000
vt -1.000000 0.000000
vt -2.000000 0.000000
vt -1.000000 -1.000000
vt 0.000000 0.000000
vt 0.000000 -1.000000
vt 1.000000 0.000000
vt 1.000000 -1.000000
vt 2.000000 -0.000000
vt 1.000000 1.000000
vt 0.000000 1.000000
vt 0.000000 -2.000000
vt 2.000000 -1.000000
vt 1.000000 -2.000000
vn -1.0000 0.0000 0.0000
vn 0.0000 0.0000 -1.0000
vn 1.0000 0.0000 0.0000
vn 0.0000 0.0000 1.0000
vn 0.0000 -1.0000 0.0000
vn 0.0000 1.0000 0.0000
usemtl Material.001
s off
f 2/1/1 3/2/1 1/3/1
f 4/4/2 7/5/2 3/2/2
f 8/6/3 5/7/3 7/5/3
f 6/8/4 1/9/4 5/7/4
f 7/5/5 1/10/5 3/11/5
f 4/12/6 6/8/6 8/6/6
f 2/1/1 4/4/1 3/2/1
f 4/4/2 8/6/2 7/5/2
f 8/6/3 6/8/3 5/7/3
f 6/8/4 2/13/4 1/9/4
f 7/5/5 5/7/5 1/10/5
f 4/12/6 2/14/6 6/8/6

Binary file not shown.

After

Width:  |  Height:  |  Size: 457 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

View File

@ -0,0 +1,10 @@
# Blender MTL File: 'None'
# Material Count: 1
newmtl None
Ns 100
Ka 0.8 0.8 0.8
Kd 0.8 0.8 0.8
Ks 0.8 0.8 0.8
d 1
illum 2

View File

@ -1,5 +1,6 @@
# Blender v2.93.3 OBJ File: '' # Blender v2.93.3 OBJ File: ''
# www.blender.org # www.blender.org
mtllib cone.mtl
o Cone o Cone
v 0.000000 -1.000000 -1.000000 v 0.000000 -1.000000 -1.000000
v 0.195090 -1.000000 -0.980785 v 0.195090 -1.000000 -0.980785
@ -133,6 +134,7 @@ vn -0.4969 0.4472 -0.7437
vn -0.3423 0.4472 -0.8263 vn -0.3423 0.4472 -0.8263
vn 0.0000 -1.0000 0.0000 vn 0.0000 -1.0000 0.0000
vn -0.1745 0.4472 -0.8772 vn -0.1745 0.4472 -0.8772
usemtl None
s 1 s 1
f 1/1/1 33/2/2 2/3/3 f 1/1/1 33/2/2 2/3/3
f 2/3/3 33/2/2 3/4/4 f 2/3/3 33/2/2 3/4/4

View File

@ -0,0 +1,10 @@
# Blender MTL File: 'None'
# Material Count: 1
newmtl None
Ns 100
Ka 0.8 0.8 0.8
Kd 0.8 0.8 0.8
Ks 0.8 0.8 0.8
d 1
illum 2

View File

@ -1,6 +1,7 @@
# Blender v2.93.3 OBJ File: '' # Blender v2.93.3 OBJ File: ''
# www.blender.org # www.blender.org
o Cube_Cube.002 mtllib cube.mtl
o Cube_Cube.001
v -1.000000 -1.000000 1.000000 v -1.000000 -1.000000 1.000000
v -1.000000 1.000000 1.000000 v -1.000000 1.000000 1.000000
v -1.000000 -1.000000 -1.000000 v -1.000000 -1.000000 -1.000000
@ -29,6 +30,7 @@ vn 1.0000 0.0000 0.0000
vn 0.0000 0.0000 1.0000 vn 0.0000 0.0000 1.0000
vn 0.0000 -1.0000 0.0000 vn 0.0000 -1.0000 0.0000
vn 0.0000 1.0000 0.0000 vn 0.0000 1.0000 0.0000
usemtl None
s off s off
f 2/1/1 3/2/1 1/3/1 f 2/1/1 3/2/1 1/3/1
f 4/4/2 7/5/2 3/2/2 f 4/4/2 7/5/2 3/2/2

View File

@ -0,0 +1,10 @@
# Blender MTL File: 'None'
# Material Count: 1
newmtl None
Ns 100
Ka 0.8 0.8 0.8
Kd 0.8 0.8 0.8
Ks 0.8 0.8 0.8
d 1
illum 2

View File

@ -1,6 +1,7 @@
# Blender v2.93.3 OBJ File: '' # Blender v2.93.3 OBJ File: ''
# www.blender.org # www.blender.org
o Cylinder mtllib cylinder.mtl
o Cylinder_Cylinder.001
v 0.000000 -1.000000 -1.000000 v 0.000000 -1.000000 -1.000000
v 0.000000 1.000000 -1.000000 v 0.000000 1.000000 -1.000000
v 0.195090 -1.000000 -0.980785 v 0.195090 -1.000000 -0.980785
@ -229,6 +230,7 @@ vn -0.3827 0.0000 -0.9239
vn 0.0000 1.0000 -0.0000 vn 0.0000 1.0000 -0.0000
vn -0.1951 0.0000 -0.9808 vn -0.1951 0.0000 -0.9808
vn 0.0000 -1.0000 0.0000 vn 0.0000 -1.0000 0.0000
usemtl None
s 1 s 1
f 2/1/1 3/2/2 1/3/1 f 2/1/1 3/2/2 1/3/1
f 4/4/2 5/5/3 3/2/2 f 4/4/2 5/5/3 3/2/2

View File

@ -0,0 +1,10 @@
# Blender MTL File: 'None'
# Material Count: 1
newmtl None
Ns 100
Ka 0.8 0.8 0.8
Kd 0.8 0.8 0.8
Ks 0.8 0.8 0.8
d 1
illum 2

View File

@ -1,5 +1,6 @@
# Blender v2.93.3 OBJ File: '' # Blender v2.93.3 OBJ File: ''
# www.blender.org # www.blender.org
mtllib plane.mtl
o Plane o Plane
v -1.000000 0.000000 1.000000 v -1.000000 0.000000 1.000000
v 1.000000 0.000000 1.000000 v 1.000000 0.000000 1.000000
@ -10,6 +11,7 @@ vt 0.000000 1.000000
vt 0.000000 0.000000 vt 0.000000 0.000000
vt 1.000000 1.000000 vt 1.000000 1.000000
vn 0.0000 1.0000 0.0000 vn 0.0000 1.0000 0.0000
usemtl None
s off s off
f 2/1/1 3/2/1 1/3/1 f 2/1/1 3/2/1 1/3/1
f 2/1/1 4/4/1 3/2/1 f 2/1/1 4/4/1 3/2/1

View File

@ -0,0 +1,10 @@
# Blender MTL File: 'None'
# Material Count: 1
newmtl None
Ns 100
Ka 0.8 0.8 0.8
Kd 0.8 0.8 0.8
Ks 0.8 0.8 0.8
d 1
illum 2

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,10 @@
# Blender MTL File: 'None'
# Material Count: 1
newmtl None
Ns 100
Ka 0.8 0.8 0.8
Kd 0.8 0.8 0.8
Ks 0.8 0.8 0.8
d 1
illum 2

View File

@ -1,5 +1,6 @@
# Blender v2.93.3 OBJ File: '' # Blender v2.93.3 OBJ File: ''
# www.blender.org # www.blender.org
mtllib torus.mtl
o Torus o Torus
v 1.250000 0.000000 0.000000 v 1.250000 0.000000 0.000000
v 1.216506 0.125000 0.000000 v 1.216506 0.125000 0.000000
@ -1742,6 +1743,7 @@ vn 0.5036 -0.8614 0.0663
vn 0.8612 -0.4954 0.1134 vn 0.8612 -0.4954 0.1134
vn -0.8559 0.5047 -0.1127 vn -0.8559 0.5047 -0.1127
vn -0.4876 -0.8707 -0.0642 vn -0.4876 -0.8707 -0.0642
usemtl None
s 1 s 1
f 13/1/1 2/2/2 1/3/3 f 13/1/1 2/2/2 1/3/3
f 2/2/2 15/4/4 3/5/5 f 2/2/2 15/4/4 3/5/5

View File

@ -9,8 +9,12 @@ struct Camera {
}; };
struct Material { struct Material {
float shininess; bool hasDiffuseTex;
//Do I want a specular color here? sampler2D diffuseTexture;
vec3 diffuseColor;
bool hasSpecTex;
sampler2D specularTexture;
float specPower;
}; };
struct Light { struct Light {
@ -21,7 +25,6 @@ struct Light {
float strength; float strength;
}; };
uniform sampler2D modelTexture;
uniform Camera camera; uniform Camera camera;
uniform Material material; uniform Material material;
uniform Light light[100]; uniform Light light[100];
@ -30,13 +33,21 @@ uniform int numberOfLights;
out vec4 outColor; out vec4 outColor;
void main() { void main() {
vec4 texColor = texture(modelTexture, texCoord);
vec3 color = vec3(0.0); vec3 color = vec3(0.0);
vec3 matDiff;
if (material.hasDiffuseTex)
matDiff = texture(material.diffuseTexture, texCoord).rgb;
else
matDiff = material.diffuseColor;
vec3 matSpec = vec3(1.0);
if(material.hasSpecTex)
matSpec = texture(material.specularTexture, texCoord).rgb;
for (int i = 0; i < numberOfLights; i++) { for (int i = 0; i < numberOfLights; i++) {
float ambientStrength = 0.2f; float ambientStrength = 0.2f;
vec3 ambient = ambientStrength * texColor.rgb; vec3 ambient = ambientStrength * matDiff;
if (i == numberOfLights - 1 && numberOfLights == 1) { if (i == numberOfLights - 1 && numberOfLights == 1) {
color += ambient; color += ambient;
break; break;
@ -46,12 +57,12 @@ void main() {
vec3 lightDir = normalize(-light[i].pos); vec3 lightDir = normalize(-light[i].pos);
vec3 norm = normalize(normals); vec3 norm = normalize(normals);
float diff = max(dot(norm, lightDir), 0.0); float diff = max(dot(norm, lightDir), 0.0);
vec3 diffuse = light[i].color * (diff * texColor.rgb) * light[i].strength; vec3 diffuse = light[i].color * (diff * matDiff) * (light[i].strength / 2.0f);
vec3 viewDir = normalize(camera.pos - fragPos); vec3 viewDir = normalize(camera.pos - fragPos);
vec3 reflectDir = reflect(-lightDir, norm); vec3 reflectDir = reflect(-lightDir, norm);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess * 32.0f); float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.specPower);
vec3 specular = light[i].color * spec * light[i].strength; vec3 specular = light[i].color * spec * matSpec * (light[i].strength / 2.0f);
color += (ambient + diffuse + specular); color += (ambient + diffuse + specular);
continue; continue;
@ -60,12 +71,12 @@ void main() {
vec3 lightDir = normalize(light[i].pos - fragPos); vec3 lightDir = normalize(light[i].pos - fragPos);
vec3 norm = normalize(normals); vec3 norm = normalize(normals);
float diff = max(dot(norm, lightDir), 0.0); float diff = max(dot(norm, lightDir), 0.0);
vec3 diffuse = light[i].color * (diff * texColor.rgb) * light[i].strength; vec3 diffuse = light[i].color * (diff * matDiff) * (light[i].strength / 2.0f);
vec3 viewDir = normalize(camera.pos - fragPos); vec3 viewDir = normalize(camera.pos - fragPos);
vec3 reflectDir = reflect(-lightDir, norm); vec3 reflectDir = reflect(-lightDir, norm);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess * 32.0f); float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.specPower);
vec3 specular = light[i].color * spec * (light[i].strength) / 8.0f; vec3 specular = light[i].color * spec * matSpec * (light[i].strength / 2.0f);
float length = length(light[i].pos - fragPos); float length = length(light[i].pos - fragPos);
float att = clamp(10.0 / length, 0.0, 1.0) * light[i].strength; float att = clamp(10.0 / length, 0.0, 1.0) * light[i].strength;
@ -74,5 +85,5 @@ void main() {
continue; continue;
} }
} }
outColor = vec4(color, texColor.a); outColor = vec4(color, 1.0);
} }

View File

@ -64,6 +64,22 @@ void writeFile(const std::string& filename, const std::string& in, bool encrypte
out.close(); out.close();
} }
void getNeededImages(std::string mtl, std::set<std::string>& set) {
while (mtl.size()) {
unsigned int pos = mtl.find("map_");
if (pos == std::string::npos)
break;
mtl = mtl.substr(pos + 7);
std::stringstream ss(mtl);
std::string temp;
ss >> temp;
unsigned int pos2 = temp.find_last_of("/\\");
if (pos2 != std::string::npos)
temp = temp.substr(pos2 + 1);
set.insert(temp);
}
}
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
Log("Starting up"); Log("Starting up");
@ -84,6 +100,7 @@ int main(int argc, char* argv[]) {
continue; continue;
std::string filename = currDir.path().filename().string().append(".nfpack"); std::string filename = currDir.path().filename().string().append(".nfpack");
Log("Creating pack \"" + filename + (std::string)"\""); Log("Creating pack \"" + filename + (std::string)"\"");
std::string currFileExtension;
std::string currFileContents; std::string currFileContents;
std::stringstream out; std::stringstream out;
unsigned int fileCount = 0; unsigned int fileCount = 0;
@ -91,11 +108,46 @@ int main(int argc, char* argv[]) {
if (curr.is_directory()) if (curr.is_directory())
continue; continue;
std::filesystem::path relative = std::filesystem::relative(curr, currDir); std::filesystem::path relative = std::filesystem::relative(curr, currDir);
if (extensions.find(relative.extension().string().substr(1)) == extensions.end()) currFileExtension = relative.extension().string().substr(1);
if (currFileExtension == "mtl")
continue;
if (extensions.find(currFileExtension) == extensions.end())
Error("File \"" + relative.string() + (std::string)"\" is not of supported type!"); Error("File \"" + relative.string() + (std::string)"\" is not of supported type!");
Log("Current file: " + relative.string()); Log("Current file: " + relative.string());
currFileContents = readFile(curr.path().string()); currFileContents = readFile(curr.path().string());
if (currFileExtension == "obj") {
std::filesystem::path mtlPath;
for (const auto& curr2 : std::filesystem::recursive_directory_iterator(curr.path().parent_path())) {
if (curr2.is_directory())
continue;
if (curr2.path().extension() != ".mtl")
continue;
std::string mtlFile = relative.filename().string().substr(0, relative.filename().string().size() - 4) + (std::string)".mtl";
if (curr2.path().filename().string() == mtlFile) {
mtlPath = curr2.path();
break;
}
}
if (mtlPath.empty())
Error("No mtl file found for " + relative.filename().string() + (std::string)"!");
Log("Found mtl file for " + relative.filename().string());
std::set<std::string> neededImages;
std::string mtlContents = readFile(mtlPath.string());
getNeededImages(mtlContents, neededImages);
if (!neededImages.empty()) {
currFileContents.insert(0, "\n");
for(std::string curr : neededImages) {
currFileContents.insert(0, curr);
currFileContents.insert(0, " ");
}
currFileContents = currFileContents.substr(1);
}
else {
currFileContents.insert(0, "none\n");
}
currFileContents += '\n' + mtlContents;
}
if (out.rdbuf()->in_avail() != 0) if (out.rdbuf()->in_avail() != 0)
out << "\n"; out << "\n";
out << "#NFASSET " + curr.path().filename().string(); out << "#NFASSET " + curr.path().filename().string();

View File

@ -1,5 +1,7 @@
#include "Assets.h" #include "Assets.h"
#include <sstream>
#include "Application.h" #include "Application.h"
#include "Model.h" #include "Model.h"
#include "Utility.h" #include "Utility.h"
@ -9,11 +11,11 @@ namespace nf {
delete[] data; delete[] data;
} }
AModel::~AModel() { ATexture::~ATexture() {
} }
ATexture::~ATexture() { AModel::~AModel() {
} }
@ -41,6 +43,7 @@ namespace nf {
void AssetPack::load(const char* packName) { void AssetPack::load(const char* packName) {
std::string path = "assets/" + (std::string)packName; std::string path = "assets/" + (std::string)packName;
std::string packContents = readFile(path); std::string packContents = readFile(path);
std::string packContentsOBJ = packContents;
std::unordered_map<std::string, ACubemap*> cubemaps; std::unordered_map<std::string, ACubemap*> cubemaps;
unsigned int cubemapCount = 0; unsigned int cubemapCount = 0;
while (packContents.size()) { while (packContents.size()) {
@ -63,18 +66,8 @@ namespace nf {
} }
size_t assetSize = assetContents.size(); size_t assetSize = assetContents.size();
if (extension == "obj") { 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;
continue; continue;
}
if (extension == "png") { 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) { 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('_')); std::string cmName = assetName.substr(0, assetName.find('_'));
@ -156,6 +149,48 @@ namespace nf {
} }
if (cubemapCount % 6 != 0) if (cubemapCount % 6 != 0)
Error("Could not find full cubemap in pack \"" + (std::string)packName + (std::string)"\"!"); 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") if (packName != "base.nfpack")
Application::getApp()->getCurrentState()->m_nfObjects.push_back(this); Application::getApp()->getCurrentState()->m_nfObjects.push_back(this);
} }

View File

@ -9,7 +9,7 @@ namespace nf {
Log("Intro onEnter!"); Log("Intro onEnter!");
m_logoTex.create(BaseAssets::logo, Vec2(0.0, 0.0)); m_logoTex.create(BaseAssets::logo, Vec2(0.0, 0.0));
m_logoTex.centered(true, true); 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_text.setScale(0.6);
m_start = std::chrono::steady_clock::now(); m_start = std::chrono::steady_clock::now();
} }

View File

@ -17,26 +17,14 @@ namespace nf {
} }
void Entity::create(Asset* modelAsset, Asset* textureAsset) { void Entity::create(Asset* modelAsset) {
m_constructed = true; m_constructed = true;
AModel& model = *(AModel*)modelAsset; AModel& model = *(AModel*)modelAsset;
//TODO: Change this when doing materials if (model.alreadyLoaded) {
if (model.alreadyLoaded && textureAsset == nullptr) {
m_model = model.loadedModel; m_model = model.loadedModel;
} }
else { else {
if (!textureAsset) m_model = new Model(&model);
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);
model.alreadyLoaded = true; model.alreadyLoaded = true;
model.loadedModel = m_model; model.loadedModel = m_model;
} }
@ -76,10 +64,10 @@ namespace nf {
m_scale = scale; m_scale = scale;
} }
void Entity::bind(Shader* shader) { void Entity::render(Shader* shader) {
m_model->bind();
shader->bind(); shader->bind();
setModelMatrix(shader); setModelMatrix(shader);
m_model->render(shader);
} }
Model* Entity::getModel() const { Model* Entity::getModel() const {
@ -101,15 +89,9 @@ namespace nf {
if(m_model && !m_model->isBaseAsset()) if(m_model && !m_model->isBaseAsset())
delete m_model; delete m_model;
m_model = nullptr; m_model = nullptr;
m_position.x = 0.0; m_position = Vec3(0.0);
m_position.y = 0.0; m_rotation = Vec3(0.0);
m_position.z = 0.0; m_scale = Vec3(1.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;
} }
Entity::~Entity() { Entity::~Entity() {

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_constructed = true;
m_position = position; m_position = position;
m_color = color; m_color = color;
m_type = type; m_type = type;
m_strength = strength; m_strength = (float)strength;
Application::getApp()->getCurrentState()->m_nfObjects.push_back(this); Application::getApp()->getCurrentState()->m_nfObjects.push_back(this);
} }

View File

@ -1,49 +1,284 @@
#include "Model.h" #include "Model.h"
#include <map>
#include "glm/glm.hpp" #include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp" #include "glm/gtc/matrix_transform.hpp"
#include "GL/glew.h"
#include "Utility.h"
#include "Texture.h" #include "Texture.h"
#include "Shader.h"
#include "Utility.h"
namespace nf { namespace nf {
Model::Model() : 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_base(false), m_vao = new VertexArray();
m_texture(nullptr) m_vao->addBuffer(vb, vbSize);
{
}
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);
m_vao->push<float>(3); m_vao->push<float>(3);
m_vao->finishBufferLayout(); m_vao->finishBufferLayout();
m_vao->addBuffer(textureCoordinatesBufferData, textureCoordinatesBufferSize); m_vao->addBuffer(tc, tcSize);
m_vao->push<float>(2); m_vao->push<float>(2);
m_vao->finishBufferLayout(); m_vao->finishBufferLayout();
m_vao->addBuffer(normalsBufferData, normalsBufferSize); m_vao->addBuffer(vn, vnSize);
m_vao->push<float>(3); m_vao->push<float>(3);
m_vao->finishBufferLayout(); m_vao->finishBufferLayout();
if (texture->alreadyLoaded) { m_ib = new IndexBuffer(ib, ibCount);
m_texture = texture->loadedTexture; if (diffTex) {
m_hasDiffuse = true;
m_diffuseTexture = new Texture(diffTex);
} }
else { m_diffColor = diffColor;
m_texture = new Texture; if (specTex) {
m_texture->create(texture); m_hasSpecular = true;
texture->alreadyLoaded = true; m_specularTexture = new Texture(specTex);
texture->loadedTexture = m_texture;
} }
m_ib = new IndexBuffer(indexBufferData, indexBufferCount); m_shininess = shininess;
} }
void Model::bind() { void Material::render(Shader* shader) {
if (m_vao == nullptr)
Error("Tried to bind uninitialized model!");
m_vao->bind(); m_vao->bind();
if (m_texture)
m_texture->bind();
m_ib->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) { void Model::setBaseAsset(bool isBase) {
@ -55,6 +290,8 @@ namespace nf {
} }
Model::~Model() { Model::~Model() {
delete m_texture; for (Material* curr : m_materials) {
delete curr;
}
} }
} }

View File

@ -136,9 +136,11 @@ namespace nf {
1.0, 1.0, 1.0, 1.0,
1.0, 0.0 1.0, 0.0
}; };
glActiveTexture(GL_TEXTURE10);
glBindTexture(GL_TEXTURE_2D, c.texID); glBindTexture(GL_TEXTURE_2D, c.texID);
m_vao->setBufferData(0, vb, sizeof(vb)); m_vao->setBufferData(0, vb, sizeof(vb));
m_vao->setBufferData(1, tc, sizeof(tc)); m_vao->setBufferData(1, tc, sizeof(tc));
shader->setUniform("text", 10);
glDrawArrays(GL_TRIANGLES, 0, 6); glDrawArrays(GL_TRIANGLES, 0, 6);
currX += (c.advance >> 6) * scale * m_scale; currX += (c.advance >> 6) * scale * m_scale;
} }

View File

@ -25,8 +25,7 @@ namespace nf {
m_texture = tex->loadedTexture; m_texture = tex->loadedTexture;
} }
else { else {
m_texture = new Texture; m_texture = new Texture(tex);
m_texture->create(tex);
} }
m_vao = new VertexArray; m_vao = new VertexArray;

View File

@ -155,15 +155,12 @@ namespace nf {
m_entityShader->setUniform("proj", proj); m_entityShader->setUniform("proj", proj);
for (Entity* draw : m_lGame) { for (Entity* draw : m_lGame) {
Entity& curr = *draw; Entity& curr = *draw;
curr.bind(m_entityShader);
//TODO: Clean this up a bit //TODO: Clean this up a bit
m_entityShader->setUniform("numberOfLights", (int)m_lights.size() + 1); m_entityShader->setUniform("numberOfLights", (int)m_lights.size() + 1);
for (unsigned int i = 0; i < m_lights.size(); i++) { for (unsigned int i = 0; i < m_lights.size(); i++) {
m_lights[i]->bind(m_entityShader, i); m_lights[i]->bind(m_entityShader, i);
} }
//TODO: Bind and draw every material here curr.render(m_entityShader);
m_entityShader->setUniform("material.shininess", 1.0f);
glDrawElements(GL_TRIANGLES, curr.getModel()->getIndexCount(), GL_UNSIGNED_INT, nullptr);
} }
m_lGame.clear(); m_lGame.clear();
m_lights.clear(); m_lights.clear();
@ -203,7 +200,9 @@ namespace nf {
m_loadingText.setOpacity(opacity); m_loadingText.setOpacity(opacity);
m_loadingText.render(m_textShader, m_app->getConfig().width, m_app->getConfig().height); 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) { if (opacity <= 0.0) {
m_fadeIn = false; m_fadeIn = false;
m_fadeOutComplete = false; m_fadeOutComplete = false;
@ -221,7 +220,7 @@ namespace nf {
m_loadingText.setOpacity(opacity); m_loadingText.setOpacity(opacity);
m_loadingText.render(m_textShader, m_app->getConfig().width, m_app->getConfig().height); 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) { if (opacity >= 1.0) {
m_fadeIn = false; m_fadeIn = false;
m_fadeOutComplete = true; m_fadeOutComplete = true;

View File

@ -8,16 +8,12 @@
#include "Utility.h" #include "Utility.h"
namespace nf { namespace nf {
Texture::Texture() : Texture::Texture(ATexture* tex) :
m_isBase(false), m_isBase(false),
m_id(0), m_id(0),
m_x(0), m_x(0),
m_y(0) m_y(0)
{ {
}
void Texture::create(ATexture* tex) {
int nChannels; int nChannels;
stbi_set_flip_vertically_on_load(true); 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); 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; m_isBase = tex->isBaseAsset;
} }
void Texture::bind() { void Texture::bind(unsigned int slot) {
glActiveTexture(GL_TEXTURE0 + slot);
glBindTexture(GL_TEXTURE_2D, m_id); glBindTexture(GL_TEXTURE_2D, m_id);
glActiveTexture(GL_TEXTURE0);
} }
Vec2 Texture::getDimensions() { Vec2 Texture::getDimensions() {

View File

@ -3,7 +3,6 @@
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include <fstream> #include <fstream>
#include <map>
#include "glm/glm.hpp" #include "glm/glm.hpp"
#include "Config.h" #include "Config.h"
@ -110,133 +109,6 @@ namespace nf {
} }
return read; 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 //Nvidia Optimius support

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#include <unordered_map> #include <unordered_map>
#include "NFObject.h" #include "NFObject.h"
namespace nf { namespace nf {
@ -14,12 +15,6 @@ namespace nf {
virtual ~Asset(); virtual ~Asset();
}; };
struct AModel : Asset {
Model* loadedModel = nullptr;
~AModel() override;
};
struct ATexture : Asset { struct ATexture : Asset {
size_t size = 0; size_t size = 0;
Texture* loadedTexture = nullptr; Texture* loadedTexture = nullptr;
@ -27,6 +22,14 @@ namespace nf {
~ATexture() override; ~ATexture() override;
}; };
struct AModel : Asset {
Model* loadedModel = nullptr;
std::unordered_map<std::string, ATexture*> neededTextures;
~AModel() override;
};
struct ACubemap : Asset { struct ACubemap : Asset {
char* frontData = nullptr; char* frontData = nullptr;
size_t frontSize = 0; size_t frontSize = 0;

View File

@ -11,7 +11,7 @@ namespace nf {
public: public:
Entity(); Entity();
void create(Asset* modelAsset, Asset* textureAsset = nullptr); void create(Asset* modelAsset);
bool isConstructed(); bool isConstructed();
void setPosition(double x, double y, double z); void setPosition(double x, double y, double z);
@ -22,7 +22,7 @@ namespace nf {
void setScale(double x, double y, double z); void setScale(double x, double y, double z);
void setScale(const Vec3& scale); void setScale(const Vec3& scale);
void bind(Shader* shader); void render(Shader* shader);
Model* getModel() const; Model* getModel() const;
void destroy() override; void destroy() override;

View File

@ -13,7 +13,7 @@ namespace nf {
}; };
Light(); 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(); bool isConstructed();
void setPosition(const Vec3& position); void setPosition(const Vec3& position);
void setColor(const Vec3& color); void setColor(const Vec3& color);

View File

@ -1,17 +1,34 @@
#pragma once #pragma once
#include "Drawable.h" #include "Drawable.h"
#include "Assets.h" #include "Assets.h"
#include "Utility.h"
namespace nf { namespace nf {
class Drawable; class Drawable;
class Texture; class Texture;
class Shader;
class Model : public Drawable { class Material : public Drawable {
public: 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 render(Shader* shader);
void bind() override;
~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); void setBaseAsset(bool isBase);
bool isBaseAsset(); bool isBaseAsset();
@ -19,6 +36,6 @@ namespace nf {
~Model(); ~Model();
private: private:
bool m_base; bool m_base;
Texture* m_texture; std::vector<Material*> m_materials;
}; };
} }

View File

@ -6,10 +6,9 @@ namespace nf {
class Texture { class Texture {
public: public:
Texture(); Texture(ATexture* tex);
void create(ATexture* tex); void bind(unsigned int slot = 0);
void bind();
Vec2 getDimensions(); Vec2 getDimensions();
bool isBaseAsset(); bool isBaseAsset();

View File

@ -1,7 +1,6 @@
#pragma once #pragma once
#include <chrono> #include <chrono>
#include <string> #include <string>
#include <vector>
#include <Windows.h> #include <Windows.h>
namespace nf { namespace nf {
@ -83,6 +82,4 @@ std::exit(-1);}
const wchar_t* toWide(const std::string& in); const wchar_t* toWide(const std::string& in);
void writeFile(const std::string& filename, const std::string& in, bool encrypted = false); void writeFile(const std::string& filename, const std::string& in, bool encrypted = false);
std::string readFile(const std::string& filename); 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);
} }