diff --git a/Game/src/MainState.cpp b/Game/src/MainState.cpp index caf9637..2b64a98 100644 --- a/Game/src/MainState.cpp +++ b/Game/src/MainState.cpp @@ -4,17 +4,17 @@ void MainState::onEnter() { Log("MainState onEnter!"); camera->setType(nf::Camera::Type::FIRST_PERSON); ap.load("example.nfpack"); - test.create(ap["spec.obj"]); - test.setPosition(0.0, 0.0, -5.0); - plane.create(nf::BaseAssets::plane); - plane.setPosition(0.0, -2.0, 0.0); - plane.setScale(10.0); + test.create(ap["normal.obj"]); + test.setPosition(0.0, 0.05, -5.0); + plane.create(nf::BaseAssets::cube); + plane.setPosition(0.0, -1.0, 0.0); + plane.setScale(50.0, 0.05, 50.0); text.create("This is a test text.", nf::Vec2(0.1, 0.025), nf::Vec3(0.8)); text.centered(true); uiTex.create(nf::BaseAssets::logo, nf::Vec2(0.025, 0.025), 0.5); button.create(nf::Vec2(0.8, 0.025), "Reset"); button2.create(nf::Vec2(0.6, 0.025), "Play Sound"); - light.create(nf::Vec3(-5.0, 10.0, 5.0), nf::Vec3(1.0, 1.0, 1.0), 1.0); + light.create(nf::Vec3(-5.0, 10.0, 5.0), nf::Vec3(1.0, 1.0, 1.0)); cm.create(nf::BaseAssets::cubemap); sound.create(ap["sound.wav"]); @@ -51,7 +51,7 @@ void MainState::update(double deltaTime) { xrot += offset; if (app->isKeyHeld(NFI_RIGHT)) xrot -= offset; - test.setPosition(-xrot / 10.0, 0.0, -yrot / 10.0 - 5.0); + light.setPosition(nf::Vec3(-5.0, yrot / 10.0 + 10.0, 5.0)); text.setText("FPS: " + std::to_string(app->getFPS())); diff --git a/NFPackCreator/AssetBuild/base/shaders/entityFragment.shader b/NFPackCreator/AssetBuild/base/shaders/entityFragment.shader index ed4f396..1a17f33 100644 --- a/NFPackCreator/AssetBuild/base/shaders/entityFragment.shader +++ b/NFPackCreator/AssetBuild/base/shaders/entityFragment.shader @@ -16,6 +16,8 @@ struct Material { bool hasSpecTex; sampler2D specularTexture; float specPower; + bool hasNormTex; + sampler2D normalTexture; }; struct Light { @@ -96,6 +98,15 @@ void main() { if (material.hasSpecTex) matSpec = texture(material.specularTexture, texCoord).rgb; + vec3 norm; + if (material.hasNormTex) { + norm = texture(material.normalTexture, texCoord).rgb; + norm = normalize(norm * 2.0 - 1.0); + } + else { + norm = normalize(normals); + } + float ambientStrength = 0.2f; vec3 ambient = ambientStrength * matDiff; if (!isContinued) @@ -104,7 +115,6 @@ void main() { if (light[i].type == 1) { vec3 lightDir = normalize(light[i].pos - fragPos); - vec3 norm = normalize(normals); float diff = max(dot(norm, lightDir), 0.0); vec3 diffuse = light[i].color * diff * matDiff * (light[i].strength / 2.0f); @@ -119,13 +129,12 @@ void main() { } if (light[i].type == 2) { vec3 lightDir = normalize(light[i].pos - fragPos); - vec3 norm = normalize(normals); float diff = max(dot(norm, lightDir), 0.0); vec3 diffuse = light[i].color * diff * matDiff * light[i].strength; vec3 viewDir = normalize(camera.pos - fragPos); - vec3 reflectDir = reflect(-lightDir, norm); - float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.specPower); + vec3 halfway = normalize(lightDir + viewDir); + float spec = pow(max(dot(norm, halfway), 0.0), material.specPower); vec3 specular = light[i].color * spec * matSpec * (light[i].strength / 2.5f); float length = length(light[i].pos - fragPos); @@ -136,5 +145,8 @@ void main() { continue; } } + //TODO: Move this to a post-processing pass + float gamma = 2.2; + color.rgb = pow(color.rgb, vec3(1.0 / gamma)); outColor = vec4(color, 1.0); } diff --git a/NFPackCreator/AssetBuild/base/shaders/uiTextureFragment.shader b/NFPackCreator/AssetBuild/base/shaders/uiTextureFragment.shader index f91476c..23968b1 100644 --- a/NFPackCreator/AssetBuild/base/shaders/uiTextureFragment.shader +++ b/NFPackCreator/AssetBuild/base/shaders/uiTextureFragment.shader @@ -5,10 +5,13 @@ in vec2 texCoord; uniform sampler2D tex; uniform float opacity; -out vec4 color; +out vec4 outColor; void main() { vec4 texColor = texture(tex, texCoord); - - color = vec4(texColor.rgb, texColor.a * opacity); -} + vec4 color = texColor; + //TODO: Move this to a post-processing pass too + float gamma = 2.2; + color.rgb = pow(color.rgb, vec3(1.0 / gamma)); + outColor = vec4(color.rgb, texColor.a * opacity); +} \ No newline at end of file diff --git a/NFPackCreator/AssetBuild/example/models/normal.mtl b/NFPackCreator/AssetBuild/example/models/normal.mtl new file mode 100644 index 0000000..982ddec --- /dev/null +++ b/NFPackCreator/AssetBuild/example/models/normal.mtl @@ -0,0 +1,14 @@ +# Blender MTL File: 'None' +# Material Count: 1 + +newmtl mat +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 diff --git a/NFPackCreator/AssetBuild/example/models/normal.obj b/NFPackCreator/AssetBuild/example/models/normal.obj new file mode 100644 index 0000000..fe83589 --- /dev/null +++ b/NFPackCreator/AssetBuild/example/models/normal.obj @@ -0,0 +1,17 @@ +# Blender v2.93.3 OBJ File: '' +# www.blender.org +mtllib normal.mtl +o Plane_Plane.001 +v -1.000000 -1.000000 -0.000000 +v 1.000000 -1.000000 -0.000000 +v -1.000000 1.000000 0.000000 +v 1.000000 1.000000 0.000000 +vt 1.000000 0.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 1.000000 +vn 0.0000 -0.0000 1.0000 +usemtl mat +s off +f 2/1/1 3/2/1 1/3/1 +f 2/1/1 4/4/1 3/2/1 diff --git a/NFPackCreator/AssetBuild/example/textures/brickwall.jpg b/NFPackCreator/AssetBuild/example/textures/brickwall.jpg new file mode 100644 index 0000000..39478d3 Binary files /dev/null and b/NFPackCreator/AssetBuild/example/textures/brickwall.jpg differ diff --git a/NFPackCreator/AssetBuild/example/textures/brickwall_normal.jpg b/NFPackCreator/AssetBuild/example/textures/brickwall_normal.jpg new file mode 100644 index 0000000..a0a5fb6 Binary files /dev/null and b/NFPackCreator/AssetBuild/example/textures/brickwall_normal.jpg differ diff --git a/NFPackCreator/src/main.cpp b/NFPackCreator/src/main.cpp index da1f9d3..9f18b7f 100644 --- a/NFPackCreator/src/main.cpp +++ b/NFPackCreator/src/main.cpp @@ -69,7 +69,10 @@ void getNeededImages(std::string mtl, std::set& set) { unsigned int pos = mtl.find("map_"); if (pos == std::string::npos) break; - mtl = mtl.substr(pos + 7); + if (pos == mtl.find("map_Kd") || pos == mtl.find("map_Ks")) + mtl = mtl.substr(pos + 7); + else + mtl = mtl.substr(pos + 9); std::stringstream ss(mtl); std::string temp; ss >> temp; @@ -140,7 +143,7 @@ int main(int argc, char* argv[]) { getNeededImages(mtlContents, neededImages); if (!neededImages.empty()) { currFileContents.insert(0, "\n"); - for(std::string curr : neededImages) { + for (std::string curr : neededImages) { currFileContents.insert(0, curr); currFileContents.insert(0, " "); } diff --git a/NothinFancy/src/Renderer/Model.cpp b/NothinFancy/src/Renderer/Model.cpp index 60505f4..ee45bc3 100644 --- a/NothinFancy/src/Renderer/Model.cpp +++ b/NothinFancy/src/Renderer/Model.cpp @@ -10,7 +10,7 @@ #include "Utility.h" 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* ib, const unsigned int ibCount, ATexture* diffTex, Vec3& diffColor, ATexture* specTex, float shininess) { + 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, ATexture* normalTex) { m_vao = new VertexArray(); m_vao->addBuffer(vb, vbSize); m_vao->push(3); @@ -35,9 +35,16 @@ namespace nf { if (specTex->alreadyLoaded) m_specularTexture = specTex->loadedTexture; else - m_specularTexture = new Texture(specTex); + 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) { @@ -60,6 +67,13 @@ namespace nf { } 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); @@ -94,6 +108,7 @@ namespace nf { std::string diffuseTextureName; Vec3 diffuseColor; std::string specularTextureName; + std::string normalTextureName; float shininess = 1.0f; }; std::unordered_map mats; @@ -124,6 +139,11 @@ namespace nf { sscanf_s(mtl.c_str(), "\nmap_Ks %s\n", texName, (unsigned)_countof(texName)); mats[currMat]->specularTextureName = (std::string)texName; } + else if (std::strcmp(line, "map_Bump") == 0) { + char texName[100]; + sscanf_s(mtl.c_str(), "\nmap_Bump %s\n", texName, (unsigned)_countof(texName)); + mats[currMat]->normalTextureName = (std::string)texName; + } else if (std::strcmp(line, "Ns") == 0) { float s = 0.0; sscanf_s(mtl.c_str(), "\nNs %f\n", &s); @@ -277,7 +297,10 @@ namespace nf { 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)); + ATexture* norm = nullptr; + if (curr.normalTextureName.size()) + norm = model->neededTextures[curr.normalTextureName]; + 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, norm)); delete m.second; } diff --git a/NothinFancy/src/Renderer/Renderer.cpp b/NothinFancy/src/Renderer/Renderer.cpp index 3b136d9..6998dbb 100644 --- a/NothinFancy/src/Renderer/Renderer.cpp +++ b/NothinFancy/src/Renderer/Renderer.cpp @@ -387,7 +387,7 @@ namespace nf { } void Renderer::createShadowMap() { - m_texSlots = 16; + m_texSlots = 13; glGenFramebuffers(1, &m_shadowMapFBO); glBindFramebuffer(GL_FRAMEBUFFER, m_shadowMapFBO); for (unsigned int i = 0; i < m_texSlots; i++) { diff --git a/NothinFancy/src/Renderer/Texture.cpp b/NothinFancy/src/Renderer/Texture.cpp index 2d2b73f..7a728ae 100644 --- a/NothinFancy/src/Renderer/Texture.cpp +++ b/NothinFancy/src/Renderer/Texture.cpp @@ -8,7 +8,7 @@ #include "Utility.h" namespace nf { - Texture::Texture(ATexture* tex) : + Texture::Texture(ATexture* tex, bool linear) : m_isBase(false), m_id(0), m_x(0), @@ -23,10 +23,12 @@ namespace nf { glBindTexture(GL_TEXTURE_2D, m_id); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_x, m_y, 0, nChannels == 3 ? GL_RGB : GL_RGBA, GL_UNSIGNED_BYTE, texture); + glTexImage2D(GL_TEXTURE_2D, 0, linear ? GL_RGBA : GL_SRGB_ALPHA, m_x, m_y, 0, nChannels == 3 ? GL_RGB : GL_RGBA, GL_UNSIGNED_BYTE, texture); glGenerateMipmap(GL_TEXTURE_2D); stbi_image_free(texture); m_isBase = tex->isBaseAsset; + tex->alreadyLoaded = true; + tex->loadedTexture = this; } void Texture::bind(unsigned int slot) { diff --git a/NothinFancy/src/include/Model.h b/NothinFancy/src/include/Model.h index 6790c42..ed88a42 100644 --- a/NothinFancy/src/include/Model.h +++ b/NothinFancy/src/include/Model.h @@ -10,7 +10,7 @@ namespace nf { class Material : 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* ib, const unsigned int ibCount, ATexture* diffTex, Vec3& diffColor, ATexture* specTex, float shininess); + 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, ATexture* normalTex); void render(Shader* shader, bool onlyDepth); @@ -22,6 +22,8 @@ namespace nf { bool m_hasSpecular = false; Texture* m_specularTexture = nullptr; float m_shininess; + bool m_hasNormal = false; + Texture* m_normalTexture = nullptr; }; class Model { diff --git a/NothinFancy/src/include/Texture.h b/NothinFancy/src/include/Texture.h index c2e67f7..0d2c2ce 100644 --- a/NothinFancy/src/include/Texture.h +++ b/NothinFancy/src/include/Texture.h @@ -6,7 +6,7 @@ namespace nf { class Texture { public: - Texture(ATexture* tex); + Texture(ATexture* tex, bool linear = false); void bind(unsigned int slot = 0); Vec2 getDimensions();