Models now draw in a single draw call
This commit is contained in:
parent
037ad47468
commit
ba19742bfe
@ -4,7 +4,7 @@ void MainState::onEnter() {
|
|||||||
Log("MainState onEnter!");
|
Log("MainState onEnter!");
|
||||||
camera->setType(nf::Camera::Type::FIRST_PERSON);
|
camera->setType(nf::Camera::Type::FIRST_PERSON);
|
||||||
ap.load("example.nfpack");
|
ap.load("example.nfpack");
|
||||||
test.create(ap["normal.obj"]);
|
test.create(ap["2mats.obj"]);
|
||||||
test.setPosition(0.0, 0.05, -5.0);
|
test.setPosition(0.0, 0.05, -5.0);
|
||||||
plane.create(nf::BaseAssets::cube);
|
plane.create(nf::BaseAssets::cube);
|
||||||
plane.setPosition(0.0, -1.0, 0.0);
|
plane.setPosition(0.0, -1.0, 0.0);
|
||||||
@ -57,7 +57,7 @@ void MainState::update(double deltaTime) {
|
|||||||
offset += 2.0 * deltaTime;
|
offset += 2.0 * deltaTime;
|
||||||
if (app->isKeyHeld(NFI_DOWN))
|
if (app->isKeyHeld(NFI_DOWN))
|
||||||
offset -= 2.0 * deltaTime;
|
offset -= 2.0 * deltaTime;
|
||||||
test.setRotation(offset * 10.0, 0.0, 0.0);
|
test.setRotation(0.0, 0.0, -offset * 20.0);
|
||||||
|
|
||||||
light.setPosition(nf::Vec3(std::sin(circle) * 10.0, 5.0, std::cos(circle) * 10.0));
|
light.setPosition(nf::Vec3(std::sin(circle) * 10.0, 5.0, std::cos(circle) * 10.0));
|
||||||
circle += 2.0 * deltaTime;
|
circle += 2.0 * deltaTime;
|
||||||
@ -77,8 +77,8 @@ void MainState::render(nf::Renderer& renderer) {
|
|||||||
renderer.render(test);
|
renderer.render(test);
|
||||||
renderer.render(plane);
|
renderer.render(plane);
|
||||||
renderer.render(light);
|
renderer.render(light);
|
||||||
/*renderer.render(light2);
|
renderer.render(light2);
|
||||||
renderer.render(light3);*/
|
renderer.render(light3);
|
||||||
renderer.render(text);
|
renderer.render(text);
|
||||||
renderer.render(uiTex);
|
renderer.render(uiTex);
|
||||||
renderer.render(button);
|
renderer.render(button);
|
||||||
|
@ -4,19 +4,16 @@ in vec3 fragPos;
|
|||||||
in vec2 texCoord;
|
in vec2 texCoord;
|
||||||
in vec3 normal;
|
in vec3 normal;
|
||||||
in mat3 tbn;
|
in mat3 tbn;
|
||||||
|
flat in int matNum;
|
||||||
|
|
||||||
struct Material {
|
uniform bool hasDiffuseTex[32];
|
||||||
bool hasDiffuseTex;
|
uniform sampler2D diffuseTexture[32];
|
||||||
sampler2D diffuseTexture;
|
uniform vec3 diffuseColor[32];
|
||||||
vec3 diffuseColor;
|
uniform bool hasSpecTex[32];
|
||||||
bool hasSpecTex;
|
uniform sampler2D specularTexture[32];
|
||||||
sampler2D specularTexture;
|
uniform float specPower[32];
|
||||||
float specPower;
|
uniform bool hasNormTex[32];
|
||||||
bool hasNormTex;
|
uniform sampler2D normalTexture[32];
|
||||||
sampler2D normalTexture;
|
|
||||||
};
|
|
||||||
|
|
||||||
uniform Material material;
|
|
||||||
|
|
||||||
layout(location = 0) out vec3 pos;
|
layout(location = 0) out vec3 pos;
|
||||||
layout(location = 1) out vec3 normals;
|
layout(location = 1) out vec3 normals;
|
||||||
@ -25,25 +22,9 @@ layout(location = 3) out vec3 specular;
|
|||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
pos = fragPos;
|
pos = fragPos;
|
||||||
|
normals = hasNormTex[matNum] ? normalize(tbn * (texture(normalTexture[matNum], texCoord).xyz * 2.0 - 1.0)) : normal;
|
||||||
if (material.hasNormTex) {
|
diffuse = hasDiffuseTex[matNum] ? texture(diffuseTexture[matNum], texCoord).rgb : diffuseColor[matNum];
|
||||||
normals = texture(material.normalTexture, texCoord).xyz;
|
specular.r = specPower[matNum];
|
||||||
normals = normals * 2.0 - 1.0;
|
specular.g = hasSpecTex[matNum] ? texture(specularTexture[matNum], texCoord).r : 1.0;
|
||||||
normals = normalize(tbn * normals);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
normals = normal;
|
|
||||||
|
|
||||||
|
|
||||||
if (material.hasDiffuseTex)
|
|
||||||
diffuse = texture(material.diffuseTexture, texCoord).rgb;
|
|
||||||
else
|
|
||||||
diffuse = material.diffuseColor;
|
|
||||||
|
|
||||||
specular.r = material.specPower;
|
|
||||||
if (material.hasSpecTex)
|
|
||||||
specular.g = texture(material.specularTexture, texCoord).r;
|
|
||||||
else
|
|
||||||
specular.g = 1.0;
|
|
||||||
specular.b = 1.0;
|
specular.b = 1.0;
|
||||||
}
|
}
|
@ -4,6 +4,7 @@ layout(location = 0) in vec3 pos;
|
|||||||
layout(location = 1) in vec2 texCoords;
|
layout(location = 1) in vec2 texCoords;
|
||||||
layout(location = 2) in vec3 normals;
|
layout(location = 2) in vec3 normals;
|
||||||
layout(location = 3) in vec3 tangent;
|
layout(location = 3) in vec3 tangent;
|
||||||
|
layout(location = 4) in int matN;
|
||||||
|
|
||||||
uniform mat4 model;
|
uniform mat4 model;
|
||||||
uniform mat4 view;
|
uniform mat4 view;
|
||||||
@ -12,8 +13,8 @@ uniform mat4 proj;
|
|||||||
out vec3 fragPos;
|
out vec3 fragPos;
|
||||||
out vec2 texCoord;
|
out vec2 texCoord;
|
||||||
out vec3 normal;
|
out vec3 normal;
|
||||||
out vec3 tang;
|
|
||||||
out mat3 tbn;
|
out mat3 tbn;
|
||||||
|
flat out int matNum;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec4 world = model * vec4(pos, 1.0);
|
vec4 world = model * vec4(pos, 1.0);
|
||||||
@ -25,6 +26,7 @@ void main() {
|
|||||||
normal = n;
|
normal = n;
|
||||||
vec3 b = cross(n, t);
|
vec3 b = cross(n, t);
|
||||||
tbn = mat3(t, b, n);
|
tbn = mat3(t, b, n);
|
||||||
|
matNum = matN;
|
||||||
|
|
||||||
gl_Position = proj * view * world;
|
gl_Position = proj * view * world;
|
||||||
}
|
}
|
26
NFPackCreator/AssetBuild/example/models/2mats.mtl
Normal file
26
NFPackCreator/AssetBuild/example/models/2mats.mtl
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# Blender MTL File: 'None'
|
||||||
|
# Material Count: 2
|
||||||
|
|
||||||
|
newmtl mat1
|
||||||
|
Ns 225.000000
|
||||||
|
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
|
||||||
|
|
||||||
|
newmtl mat2
|
||||||
|
Ns 225.000000
|
||||||
|
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_Bump brickwall_normal.jpg
|
||||||
|
map_Kd brickwall.jpg
|
47
NFPackCreator/AssetBuild/example/models/2mats.obj
Normal file
47
NFPackCreator/AssetBuild/example/models/2mats.obj
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
# Blender v2.93.3 OBJ File: ''
|
||||||
|
# www.blender.org
|
||||||
|
mtllib 2mats.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 0.000000
|
||||||
|
vt -1.000000 1.000000
|
||||||
|
vt -2.000000 1.000000
|
||||||
|
vt -1.000000 0.000000
|
||||||
|
vt 0.000000 1.000000
|
||||||
|
vt 1.000000 0.000000
|
||||||
|
vt 2.000000 1.000000
|
||||||
|
vt 1.000000 1.000000
|
||||||
|
vt 1.000000 2.000000
|
||||||
|
vt 0.000000 2.000000
|
||||||
|
vt 0.000000 -1.000000
|
||||||
|
vt 0.000000 0.000000
|
||||||
|
vt 2.000000 0.000000
|
||||||
|
vt 1.000000 -1.000000
|
||||||
|
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 1.0000 0.0000 0.0000
|
||||||
|
usemtl mat1
|
||||||
|
s off
|
||||||
|
f 2/1/1 3/2/1 1/3/1
|
||||||
|
f 4/4/2 7/5/2 3/2/2
|
||||||
|
f 6/6/3 1/7/3 5/8/3
|
||||||
|
f 7/5/4 1/9/4 3/10/4
|
||||||
|
f 4/11/5 6/6/5 8/12/5
|
||||||
|
f 2/1/1 4/4/1 3/2/1
|
||||||
|
f 4/4/2 8/12/2 7/5/2
|
||||||
|
f 6/6/3 2/13/3 1/7/3
|
||||||
|
f 7/5/4 5/8/4 1/9/4
|
||||||
|
f 4/11/5 2/14/5 6/6/5
|
||||||
|
usemtl mat2
|
||||||
|
f 8/12/6 5/8/6 7/5/6
|
||||||
|
f 8/12/6 6/6/6 5/8/6
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
#include "Model.h"
|
#include "Model.h"
|
||||||
|
#include "Texture.h"
|
||||||
#include "Utility.h"
|
#include "Utility.h"
|
||||||
|
|
||||||
namespace nf {
|
namespace nf {
|
||||||
@ -53,9 +54,15 @@ namespace nf {
|
|||||||
m_nfObjects.clear();
|
m_nfObjects.clear();
|
||||||
|
|
||||||
for (Model* curr : m_modelsToDelete)
|
for (Model* curr : m_modelsToDelete)
|
||||||
|
if (!curr->isBaseAsset())
|
||||||
delete curr;
|
delete curr;
|
||||||
m_modelsToDelete.clear();
|
m_modelsToDelete.clear();
|
||||||
|
|
||||||
|
for (Texture* curr : m_texturesToDelete)
|
||||||
|
if (!curr->isBaseAsset())
|
||||||
|
delete curr;
|
||||||
|
m_texturesToDelete.clear();
|
||||||
|
|
||||||
delete camera;
|
delete camera;
|
||||||
app = nullptr;
|
app = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -53,10 +53,10 @@ namespace nf {
|
|||||||
};
|
};
|
||||||
m_vao = new VertexArray;
|
m_vao = new VertexArray;
|
||||||
m_vao->addBuffer(nullptr, 0);
|
m_vao->addBuffer(nullptr, 0);
|
||||||
m_vao->push<float>(2);
|
m_vao->pushFloat(2);
|
||||||
m_vao->finishBufferLayout();
|
m_vao->finishBufferLayout();
|
||||||
m_vao->addBuffer(tc, sizeof(tc));
|
m_vao->addBuffer(tc, sizeof(tc));
|
||||||
m_vao->push<float>(2);
|
m_vao->pushFloat(2);
|
||||||
m_vao->finishBufferLayout();
|
m_vao->finishBufferLayout();
|
||||||
|
|
||||||
if (!Application::getApp()->getCurrentState()->isRunning())
|
if (!Application::getApp()->getCurrentState()->isRunning())
|
||||||
|
@ -113,7 +113,7 @@ namespace nf {
|
|||||||
};
|
};
|
||||||
m_vao = new VertexArray;
|
m_vao = new VertexArray;
|
||||||
m_vao->addBuffer(vb, sizeof(vb));
|
m_vao->addBuffer(vb, sizeof(vb));
|
||||||
m_vao->push<float>(3);
|
m_vao->pushFloat(3);
|
||||||
m_vao->finishBufferLayout();
|
m_vao->finishBufferLayout();
|
||||||
|
|
||||||
if (!Application::getApp()->getCurrentState()->isRunning())
|
if (!Application::getApp()->getCurrentState()->isRunning())
|
||||||
|
@ -90,7 +90,7 @@ namespace nf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Entity::destroy() {
|
void Entity::destroy() {
|
||||||
if (m_constructed && m_model && !m_model->isBaseAsset()) {
|
if (m_constructed && m_model) {
|
||||||
Application::getApp()->getCurrentState()->m_modelsToDelete.insert(m_model);
|
Application::getApp()->getCurrentState()->m_modelsToDelete.insert(m_model);
|
||||||
m_model = nullptr;
|
m_model = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -60,10 +60,10 @@ namespace nf {
|
|||||||
}
|
}
|
||||||
m_vao = new VertexArray;
|
m_vao = new VertexArray;
|
||||||
m_vao->addBuffer(nullptr, 0);
|
m_vao->addBuffer(nullptr, 0);
|
||||||
m_vao->push<float>(2);
|
m_vao->pushFloat(2);
|
||||||
m_vao->finishBufferLayout();
|
m_vao->finishBufferLayout();
|
||||||
m_vao->addBuffer(nullptr, 0);
|
m_vao->addBuffer(nullptr, 0);
|
||||||
m_vao->push<float>(2);
|
m_vao->pushFloat(2);
|
||||||
m_vao->finishBufferLayout();
|
m_vao->finishBufferLayout();
|
||||||
|
|
||||||
if (m_string == "NFLoadingText") {
|
if (m_string == "NFLoadingText") {
|
||||||
|
@ -43,10 +43,10 @@ namespace nf {
|
|||||||
};
|
};
|
||||||
m_vao = new VertexArray;
|
m_vao = new VertexArray;
|
||||||
m_vao->addBuffer(nullptr, 0);
|
m_vao->addBuffer(nullptr, 0);
|
||||||
m_vao->push<float>(2);
|
m_vao->pushFloat(2);
|
||||||
m_vao->finishBufferLayout();
|
m_vao->finishBufferLayout();
|
||||||
m_vao->addBuffer(tc, sizeof(tc));
|
m_vao->addBuffer(tc, sizeof(tc));
|
||||||
m_vao->push<float>(2);
|
m_vao->pushFloat(2);
|
||||||
m_vao->finishBufferLayout();
|
m_vao->finishBufferLayout();
|
||||||
|
|
||||||
if (!Application::getApp()->getCurrentState()->isRunning())
|
if (!Application::getApp()->getCurrentState()->isRunning())
|
||||||
|
@ -1,96 +1,22 @@
|
|||||||
#include "Model.h"
|
#include "Model.h"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <algorithm>
|
||||||
#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 "GL/glew.h"
|
||||||
|
|
||||||
|
#include "Application.h"
|
||||||
#include "Texture.h"
|
#include "Texture.h"
|
||||||
#include "Shader.h"
|
#include "Shader.h"
|
||||||
#include "Utility.h"
|
#include "Utility.h"
|
||||||
|
|
||||||
namespace nf {
|
namespace nf {
|
||||||
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* tan, const size_t tanSize, const void* ib, const unsigned int ibCount, ATexture* diffTex, Vec3& diffColor, ATexture* specTex, float shininess, ATexture* normalTex) {
|
|
||||||
m_vao = new VertexArray();
|
|
||||||
m_vao->addBuffer(vb, vbSize);
|
|
||||||
m_vao->push<float>(3);
|
|
||||||
m_vao->finishBufferLayout();
|
|
||||||
m_vao->addBuffer(tc, tcSize);
|
|
||||||
m_vao->push<float>(2);
|
|
||||||
m_vao->finishBufferLayout();
|
|
||||||
m_vao->addBuffer(vn, vnSize);
|
|
||||||
m_vao->push<float>(3);
|
|
||||||
m_vao->finishBufferLayout();
|
|
||||||
m_vao->addBuffer(tan, tanSize);
|
|
||||||
m_vao->push<float>(3);
|
|
||||||
m_vao->finishBufferLayout();
|
|
||||||
m_ib = new IndexBuffer(ib, ibCount);
|
|
||||||
if (diffTex) {
|
|
||||||
m_hasDiffuse = true;
|
|
||||||
if (diffTex->alreadyLoaded)
|
|
||||||
m_diffuseTexture = diffTex->loadedTexture;
|
|
||||||
else
|
|
||||||
m_diffuseTexture = new Texture(diffTex);
|
|
||||||
}
|
|
||||||
m_diffColor = diffColor;
|
|
||||||
if (specTex) {
|
|
||||||
m_hasSpecular = true;
|
|
||||||
if (specTex->alreadyLoaded)
|
|
||||||
m_specularTexture = specTex->loadedTexture;
|
|
||||||
else
|
|
||||||
m_specularTexture = new Texture(specTex, true);
|
|
||||||
}
|
|
||||||
m_shininess = shininess;
|
|
||||||
if (normalTex) {
|
|
||||||
m_hasNormal = true;
|
|
||||||
if (normalTex->alreadyLoaded)
|
|
||||||
m_normalTexture = normalTex->loadedTexture;
|
|
||||||
else
|
|
||||||
m_normalTexture = new Texture(normalTex, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Material::render(Shader* shader, bool onlyDepth) {
|
|
||||||
m_vao->bind();
|
|
||||||
m_ib->bind();
|
|
||||||
if (!onlyDepth) {
|
|
||||||
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);
|
|
||||||
if (m_hasNormal) {
|
|
||||||
shader->setUniform("material.hasNormTex", true);
|
|
||||||
m_normalTexture->bind(2);
|
|
||||||
shader->setUniform("material.normalTexture", 2);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
shader->setUniform("material.hasNormTex", 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;
|
|
||||||
delete m_normalTexture;
|
|
||||||
}
|
|
||||||
|
|
||||||
Model::Model(AModel* model) :
|
Model::Model(AModel* model) :
|
||||||
m_base(model->isBaseAsset)
|
m_base(model->isBaseAsset)
|
||||||
{
|
{
|
||||||
|
if (model->neededTextures.size() > 32)
|
||||||
|
Error("Model exceedes 32 texture limit!");
|
||||||
std::string obj = model->data;
|
std::string obj = model->data;
|
||||||
unsigned int startMtlPos = obj.find("newmtl");
|
unsigned int startMtlPos = obj.find("newmtl");
|
||||||
if (startMtlPos == std::string::npos)
|
if (startMtlPos == std::string::npos)
|
||||||
@ -293,6 +219,13 @@ namespace nf {
|
|||||||
return std::memcmp((void*)this, (void*)&other, sizeof(Vertex)) > 0;
|
return std::memcmp((void*)this, (void*)&other, sizeof(Vertex)) > 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
std::vector<float> vboPositions;
|
||||||
|
std::vector<float> vboTexCoords;
|
||||||
|
std::vector<float> vboNormals;
|
||||||
|
std::vector<float> vboTangents;
|
||||||
|
std::vector<int> vboMaterialIndices;
|
||||||
|
std::vector<unsigned int> vboIndices;
|
||||||
|
int matCount = 0;
|
||||||
for (auto& m : mats) {
|
for (auto& m : mats) {
|
||||||
std::string curr = m.first;
|
std::string curr = m.first;
|
||||||
std::map<Vertex, unsigned int> vertexMap;
|
std::map<Vertex, unsigned int> vertexMap;
|
||||||
@ -325,23 +258,101 @@ namespace nf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TempMaterial& curr2 = *m.second;
|
TempMaterial& curr2 = *m.second;
|
||||||
ATexture* diff = nullptr;
|
ATexture* diffA = nullptr;
|
||||||
if (curr2.diffuseTextureName.size())
|
Texture* diff = nullptr;
|
||||||
diff = model->neededTextures[curr2.diffuseTextureName];
|
if (curr2.diffuseTextureName.size()) {
|
||||||
ATexture* spec = nullptr;
|
diffA = model->neededTextures[curr2.diffuseTextureName];
|
||||||
if (curr2.specularTextureName.size())
|
diff = new Texture(diffA);
|
||||||
spec = model->neededTextures[curr2.specularTextureName];
|
|
||||||
ATexture* norm = nullptr;
|
|
||||||
if (curr2.normalTextureName.size())
|
|
||||||
norm = model->neededTextures[curr2.normalTextureName];
|
|
||||||
m_materials.push_back(new Material(&curr2.outVB[0], curr2.outVB.size() * sizeof(float), &curr2.outTC[0], curr2.outTC.size() * sizeof(float), &curr2.outVN[0], curr2.outVN.size() * sizeof(float), &curr2.outTan[0], curr2.outTan.size() * sizeof(float), &curr2.outIB[0], curr2.ibCount, diff, curr2.diffuseColor, spec, curr2.shininess, norm));
|
|
||||||
delete m.second;
|
|
||||||
}
|
}
|
||||||
|
ATexture* specA = nullptr;
|
||||||
|
Texture* spec = nullptr;
|
||||||
|
if (curr2.specularTextureName.size()) {
|
||||||
|
specA = model->neededTextures[curr2.specularTextureName];
|
||||||
|
spec = new Texture(specA, true);
|
||||||
|
}
|
||||||
|
ATexture* normA = nullptr;
|
||||||
|
Texture* norm = nullptr;
|
||||||
|
if (curr2.normalTextureName.size()) {
|
||||||
|
normA = model->neededTextures[curr2.normalTextureName];
|
||||||
|
norm = new Texture(normA, true);
|
||||||
|
}
|
||||||
|
m_materials.push_back(std::make_tuple(diff, spec, norm, (float)curr2.diffuseColor.x, (float)curr2.diffuseColor.y, (float)curr2.diffuseColor.z, curr2.shininess));
|
||||||
|
unsigned int offset = vboPositions.size() / 3;
|
||||||
|
vboPositions.insert(vboPositions.end(), curr2.outVB.begin(), curr2.outVB.end());
|
||||||
|
vboTexCoords.insert(vboTexCoords.end(), curr2.outTC.begin(), curr2.outTC.end());
|
||||||
|
vboNormals.insert(vboNormals.end(), curr2.outVN.begin(), curr2.outVN.end());
|
||||||
|
vboTangents.insert(vboTangents.end(), curr2.outTan.begin(), curr2.outTan.end());
|
||||||
|
vboMaterialIndices.insert(vboMaterialIndices.end(), curr2.outVB.size() / 3, matCount);
|
||||||
|
if (offset)
|
||||||
|
std::for_each(curr2.outIB.begin(), curr2.outIB.end(), [offset](unsigned int& out) { out += offset; });
|
||||||
|
vboIndices.insert(vboIndices.end(), curr2.outIB.begin(), curr2.outIB.end());
|
||||||
|
delete m.second;
|
||||||
|
matCount++;
|
||||||
|
}
|
||||||
|
if (m_materials.size() > 32)
|
||||||
|
Error("Model exceedes 32 material limit!");
|
||||||
|
m_vao = new VertexArray;
|
||||||
|
m_vao->addBuffer(&vboPositions[0], vboPositions.size() * sizeof(float));
|
||||||
|
m_vao->pushFloat(3);
|
||||||
|
m_vao->finishBufferLayout();
|
||||||
|
m_vao->addBuffer(&vboTexCoords[0], vboTexCoords.size() * sizeof(float));
|
||||||
|
m_vao->pushFloat(2);
|
||||||
|
m_vao->finishBufferLayout();
|
||||||
|
m_vao->addBuffer(&vboNormals[0], vboNormals.size() * sizeof(float));
|
||||||
|
m_vao->pushFloat(3);
|
||||||
|
m_vao->finishBufferLayout();
|
||||||
|
m_vao->addBuffer(&vboTangents[0], vboTangents.size() * sizeof(float));
|
||||||
|
m_vao->pushFloat(3);
|
||||||
|
m_vao->finishBufferLayout();
|
||||||
|
m_vao->addBuffer(&vboMaterialIndices[0], vboMaterialIndices.size() * sizeof(int));
|
||||||
|
m_vao->pushInt(1);
|
||||||
|
m_vao->finishBufferLayout();
|
||||||
|
m_ib = new IndexBuffer(&vboIndices[0], vboIndices.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::render(Shader* shader, bool onlyDepth) {
|
void Model::render(Shader* shader, bool onlyDepth) {
|
||||||
for (Material* curr : m_materials) {
|
m_vao->bind();
|
||||||
curr->render(shader, onlyDepth);
|
m_ib->bind();
|
||||||
|
if (!onlyDepth)
|
||||||
|
bindMaterials(shader);
|
||||||
|
glDrawElements(GL_TRIANGLES, m_ib->getCount(), GL_UNSIGNED_INT, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Model::bindMaterials(Shader* shader) {
|
||||||
|
int texSlot = 0;
|
||||||
|
for (unsigned int i = 0; i < m_materials.size(); i++) {
|
||||||
|
std::string currMatSuffix = std::to_string(i) + (std::string)"]";
|
||||||
|
Texture* diff;
|
||||||
|
if ((diff = std::get<0>(m_materials[i])) != nullptr) {
|
||||||
|
shader->setUniform(m_hasDiffString + currMatSuffix, true);
|
||||||
|
diff->bind(texSlot);
|
||||||
|
shader->setUniform(m_diffString + currMatSuffix, texSlot);
|
||||||
|
texSlot++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
shader->setUniform(m_hasDiffString + currMatSuffix, false);
|
||||||
|
glm::vec3 color(std::get<3>(m_materials[i]), std::get<4>(m_materials[i]), std::get<5>(m_materials[i]));
|
||||||
|
shader->setUniform(m_diffColorString + currMatSuffix, color);
|
||||||
|
}
|
||||||
|
Texture* spec;
|
||||||
|
if ((spec = std::get<1>(m_materials[i])) != nullptr) {
|
||||||
|
shader->setUniform(m_hasSpecString + currMatSuffix, true);
|
||||||
|
spec->bind(texSlot);
|
||||||
|
shader->setUniform(m_specString + currMatSuffix, texSlot);
|
||||||
|
texSlot++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
shader->setUniform(m_hasSpecString + currMatSuffix, false);
|
||||||
|
Texture* norm;
|
||||||
|
if ((norm = std::get<2>(m_materials[i])) != nullptr) {
|
||||||
|
shader->setUniform(m_hasNormString + currMatSuffix, true);
|
||||||
|
norm->bind(texSlot);
|
||||||
|
shader->setUniform(m_normString + currMatSuffix, texSlot);
|
||||||
|
texSlot++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
shader->setUniform(m_hasNormString + currMatSuffix, false);
|
||||||
|
shader->setUniform(m_specPowerString + currMatSuffix, std::get<6>(m_materials[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -350,8 +361,14 @@ namespace nf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Model::~Model() {
|
Model::~Model() {
|
||||||
for (Material* curr : m_materials) {
|
for (unsigned int i = 0; i < m_materials.size(); i++) {
|
||||||
delete curr;
|
Texture* curr;
|
||||||
|
if ((curr = std::get<0>(m_materials[i])) != nullptr)
|
||||||
|
Application::getApp()->getCurrentState()->m_texturesToDelete.insert(std::get<0>(m_materials[i]));
|
||||||
|
if ((curr = std::get<1>(m_materials[i])) != nullptr)
|
||||||
|
Application::getApp()->getCurrentState()->m_texturesToDelete.insert(std::get<1>(m_materials[i]));
|
||||||
|
if ((curr = std::get<2>(m_materials[i])) != nullptr)
|
||||||
|
Application::getApp()->getCurrentState()->m_texturesToDelete.insert(std::get<2>(m_materials[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -111,8 +111,8 @@ namespace nf {
|
|||||||
};
|
};
|
||||||
m_quadVAO = new VertexArray;
|
m_quadVAO = new VertexArray;
|
||||||
m_quadVAO->addBuffer(quadVB, sizeof(quadVB));
|
m_quadVAO->addBuffer(quadVB, sizeof(quadVB));
|
||||||
m_quadVAO->push<float>(2);
|
m_quadVAO->pushFloat(2);
|
||||||
m_quadVAO->push<float>(2);
|
m_quadVAO->pushFloat(2);
|
||||||
m_quadVAO->finishBufferLayout();
|
m_quadVAO->finishBufferLayout();
|
||||||
m_quadIB = new IndexBuffer(quadIB, 6);
|
m_quadIB = new IndexBuffer(quadIB, 6);
|
||||||
m_loadingText.create("NFLoadingText", Vec2(0.025, 0.044), Vec3(0.7, 0.7, 0.7));
|
m_loadingText.create("NFLoadingText", Vec2(0.025, 0.044), Vec3(0.7, 0.7, 0.7));
|
||||||
|
@ -44,8 +44,16 @@ namespace nf {
|
|||||||
glAttachShader(m_id, fs);
|
glAttachShader(m_id, fs);
|
||||||
if (gs) glAttachShader(m_id, gs);
|
if (gs) glAttachShader(m_id, gs);
|
||||||
glLinkProgram(m_id);
|
glLinkProgram(m_id);
|
||||||
glValidateProgram(m_id);
|
|
||||||
int result;
|
int result;
|
||||||
|
glGetProgramiv(m_id, GL_LINK_STATUS, &result);
|
||||||
|
if (result != GL_TRUE) {
|
||||||
|
int length;
|
||||||
|
glGetProgramiv(m_id, GL_INFO_LOG_LENGTH, &length);
|
||||||
|
char* message = new char[length];
|
||||||
|
glGetProgramInfoLog(m_id, length, &length, message);
|
||||||
|
Error("OpenGL Error: " + (std::string)message);
|
||||||
|
}
|
||||||
|
glValidateProgram(m_id);
|
||||||
glGetProgramiv(m_id, GL_VALIDATE_STATUS, &result);
|
glGetProgramiv(m_id, GL_VALIDATE_STATUS, &result);
|
||||||
if (result != GL_TRUE) {
|
if (result != GL_TRUE) {
|
||||||
int length;
|
int length;
|
||||||
|
@ -22,20 +22,29 @@ namespace nf {
|
|||||||
m_lastStride = 0;
|
m_lastStride = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
void VertexArray::pushFloat(unsigned int count) {
|
||||||
void VertexArray::push<float>(unsigned int count) {
|
|
||||||
if (m_lastBufferHasLayout)
|
if (m_lastBufferHasLayout)
|
||||||
Error("Tried to modify a vertex array's buffer after the layout was final!");
|
Error("Tried to modify a vertex array's buffer after the layout was final!");
|
||||||
m_lastBufferLayout.push_back({ GL_FLOAT, count, GL_FALSE });
|
m_lastBufferLayout.push_back({ GL_FLOAT, count, GL_FALSE });
|
||||||
m_lastStride += count * sizeof(GL_FLOAT);
|
m_lastStride += count * sizeof(GL_FLOAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VertexArray::pushInt(unsigned int count) {
|
||||||
|
if (m_lastBufferHasLayout)
|
||||||
|
Error("Tried to modify a vertex array's buffer after the layout was final!");
|
||||||
|
m_lastBufferLayout.push_back({ GL_INT, count, GL_FALSE });
|
||||||
|
m_lastStride += count * sizeof(GL_INT);
|
||||||
|
}
|
||||||
|
|
||||||
void VertexArray::finishBufferLayout() {
|
void VertexArray::finishBufferLayout() {
|
||||||
unsigned int offset = 0;
|
unsigned int offset = 0;
|
||||||
for (; m_attribute < m_lastBufferLayout.size(); m_attribute++) {
|
for (; m_attribute < m_lastBufferLayout.size(); m_attribute++) {
|
||||||
const VertexBufferElement& curr = m_lastBufferLayout[m_attribute];
|
const VertexBufferElement& curr = m_lastBufferLayout[m_attribute];
|
||||||
glEnableVertexAttribArray(m_attribute);
|
glEnableVertexAttribArray(m_attribute);
|
||||||
|
if (curr.type != GL_INT)
|
||||||
glVertexAttribPointer(m_attribute, curr.count, curr.type, curr.normalized, m_lastStride, (const void*)offset);
|
glVertexAttribPointer(m_attribute, curr.count, curr.type, curr.normalized, m_lastStride, (const void*)offset);
|
||||||
|
else
|
||||||
|
glVertexAttribIPointer(m_attribute, curr.count, curr.type, m_lastStride, (const void*)offset);
|
||||||
offset += sizeof(curr.type) * curr.count;
|
offset += sizeof(curr.type) * curr.count;
|
||||||
}
|
}
|
||||||
m_lastBufferHasLayout = true;
|
m_lastBufferHasLayout = true;
|
||||||
|
@ -17,7 +17,7 @@ namespace nf {
|
|||||||
private:
|
private:
|
||||||
void resize();
|
void resize();
|
||||||
unsigned int m_FBO;
|
unsigned int m_FBO;
|
||||||
std::array<unsigned int, 4> m_textures; //TODO: Check this number
|
std::array<unsigned int, 4> m_textures;
|
||||||
unsigned int m_depth;
|
unsigned int m_depth;
|
||||||
|
|
||||||
unsigned int m_width, m_height;
|
unsigned int m_width, m_height;
|
||||||
|
@ -10,6 +10,7 @@ namespace nf {
|
|||||||
class Renderer;
|
class Renderer;
|
||||||
class Camera;
|
class Camera;
|
||||||
class Model;
|
class Model;
|
||||||
|
class Texture;
|
||||||
|
|
||||||
class Gamestate {
|
class Gamestate {
|
||||||
public:
|
public:
|
||||||
@ -32,6 +33,7 @@ namespace nf {
|
|||||||
|
|
||||||
std::vector<NFObject*> m_nfObjects;
|
std::vector<NFObject*> m_nfObjects;
|
||||||
std::unordered_set<Model*> m_modelsToDelete;
|
std::unordered_set<Model*> m_modelsToDelete;
|
||||||
|
std::unordered_set<Texture*> m_texturesToDelete;
|
||||||
protected:
|
protected:
|
||||||
Application* app;
|
Application* app;
|
||||||
Camera* camera;
|
Camera* camera;
|
||||||
|
@ -4,39 +4,29 @@
|
|||||||
#include "Utility.h"
|
#include "Utility.h"
|
||||||
|
|
||||||
namespace nf {
|
namespace nf {
|
||||||
class Drawable;
|
|
||||||
class Texture;
|
class Texture;
|
||||||
class Shader;
|
class Shader;
|
||||||
|
|
||||||
class Material : public Drawable {
|
class Model : public Drawable {
|
||||||
public:
|
|
||||||
Material(const void* vb, const size_t vbSize, const void* tc, const size_t tcSize, const void* vn, const size_t vnSize, const void* tan, const size_t tanSize, const void* ib, const unsigned int ibCount, ATexture* diffTex, Vec3& diffColor, ATexture* specTex, float shininess, ATexture* normalTex);
|
|
||||||
|
|
||||||
void render(Shader* shader, bool onlyDepth);
|
|
||||||
|
|
||||||
~Material();
|
|
||||||
private:
|
|
||||||
bool m_hasDiffuse = false;
|
|
||||||
Texture* m_diffuseTexture = nullptr;
|
|
||||||
Vec3 m_diffColor;
|
|
||||||
bool m_hasSpecular = false;
|
|
||||||
Texture* m_specularTexture = nullptr;
|
|
||||||
float m_shininess;
|
|
||||||
bool m_hasNormal = false;
|
|
||||||
Texture* m_normalTexture = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Model {
|
|
||||||
public:
|
public:
|
||||||
Model(AModel* model);
|
Model(AModel* model);
|
||||||
|
|
||||||
void render(Shader* shader, bool onlyDepth);
|
void render(Shader* shader, bool onlyDepth);
|
||||||
|
void bindMaterials(Shader* shader);
|
||||||
|
|
||||||
bool isBaseAsset();
|
bool isBaseAsset();
|
||||||
|
|
||||||
~Model();
|
~Model();
|
||||||
private:
|
private:
|
||||||
bool m_base;
|
bool m_base;
|
||||||
std::vector<Material*> m_materials;
|
std::vector<std::tuple<Texture*, Texture*, Texture*, float, float, float, float>> m_materials;
|
||||||
|
const std::string m_hasDiffString = "hasDiffuseTex[";
|
||||||
|
const std::string m_diffString = "diffuseTexture[";
|
||||||
|
const std::string m_diffColorString = "diffuseColor[";
|
||||||
|
const std::string m_hasSpecString = "hasSpecTex[";
|
||||||
|
const std::string m_specString = "specularTexture[";
|
||||||
|
const std::string m_hasNormString = "hasNormTex[";
|
||||||
|
const std::string m_normString = "normalTexture[";
|
||||||
|
const std::string m_specPowerString = "specPower[";
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -15,8 +15,8 @@ namespace nf {
|
|||||||
VertexArray();
|
VertexArray();
|
||||||
|
|
||||||
void addBuffer(const void* data, const size_t size);
|
void addBuffer(const void* data, const size_t size);
|
||||||
template<typename T>
|
void pushFloat(unsigned int count);
|
||||||
void push(unsigned int count);
|
void pushInt(unsigned int count);
|
||||||
void finishBufferLayout();
|
void finishBufferLayout();
|
||||||
void bind();
|
void bind();
|
||||||
void setBufferData(unsigned int buffer, const void* data, const size_t dataSize);
|
void setBufferData(unsigned int buffer, const void* data, const size_t dataSize);
|
||||||
|
Reference in New Issue
Block a user