From 8fc773e0f885cfca33173146e3cfe492fb103d74 Mon Sep 17 00:00:00 2001 From: Peder Bergebakken Sundt Date: Tue, 19 Mar 2019 20:13:51 +0100 Subject: [PATCH] Add material struct, making it easier to apply properties thoughout the scene --- src/gamelogic.cpp | 34 ++++++----- src/sceneGraph.hpp | 1 + src/utilities/material.cpp | 104 ++++++++++++++++++++++++++++++++++ src/utilities/material.hpp | 43 ++++++++++++++ src/utilities/modelLoader.cpp | 38 +++++++------ src/utilities/modelLoader.hpp | 14 +---- 6 files changed, 190 insertions(+), 44 deletions(-) create mode 100644 src/utilities/material.cpp create mode 100644 src/utilities/material.hpp diff --git a/src/gamelogic.cpp b/src/gamelogic.cpp index b923900..58f086e 100644 --- a/src/gamelogic.cpp +++ b/src/gamelogic.cpp @@ -133,22 +133,24 @@ void initGame(GLFWwindow* window, CommandLineOptions gameOptions) { carNode = loadModelScene("../res/models/beetle/scene.gltf", { - {-1, Material::diffuse({0.3, 0.3, 1.0, 1.0}, 30)},// default - //{ 0, Material::diffuse({1.0, 1.0, 1.0, 1.0})},// Blue_Metal - //{ 1, Material::diffuse({1.0, 1.0, 1.0, 1.0})},// Metal - //{ 2, Material::diffuse({1.0, 1.0, 1.0, 1.0})},// Front_Light_Glass - { 3, Material::diffuse({0.2, 0.2, 0.2, 1.0})},// Black_Rubber - //{ 4, Material::diffuse({1.0, 1.0, 1.0, 1.0})},// Mirror - //{ 5, Material::diffuse({1.0, 1.0, 1.0, 1.0})},// Black_Metal - //{ 6, Material::diffuse({1.0, 1.0, 1.0, 1.0})},// Plastic - { 7, Material::diffuse({0.1, 0.1, 0.1, 1.0})},// Window_Glass - //{ 8, Material::diffuse({1.0, 1.0, 1.0, 1.0})},// Material - //{ 9, Material::diffuse({1.0, 1.0, 1.0, 1.0})},// Glossy_metal - //{10, Material::diffuse({1.0, 1.0, 1.0, 1.0})},// Rogh_Metal - //{11, Material::diffuse({1.0, 1.0, 1.0, 1.0})},// License_Plate_Metal - //{12, Material::diffuse({1.0, 1.0, 1.0, 1.0})},// License_Plate_Frame - //{13, Material::diffuse({1.0, 1.0, 1.0, 1.0})},// + { 0, Material().diffuse({0.0, 0.0, 1.0}).diffuse_only().reflection_mapped(&t_reflection, 0.15)},// Blue_Metal + { 1, Material().diffuse(vec3(0.85)).emissive(vec3(0.1)).reflection_mapped(&t_reflection, -1.0)},// Metal (decals) + //{ 2, Material().diffuse({1.0, 1.0, 1.0})},// Front_Light_Glass + // { 3, Material().diffuse({0.2, 0.2, 0.2})},// Black_Rubber + { 4, Material().no_colors().reflection_mapped(&t_reflection, 1.0)},// Mirror + //{ 5, Material().diffuse({1.0, 1.0, 1.0})},// Black_Metal + //{ 6, Material().diffuse({1.0, 1.0, 1.0})},// Plastic +// { 7, Material().diffuse(vec3(0.2)).emissive(vec3(0.25)).specular(vec3(1.0), 70).reflection_mapped(&t_reflection, -0.8)},// Window_Glass + { 7, Material().diffuse(vec3(0.2)).emissive(vec3(0.25)).specular(vec3(1.0), 70).reflection_mapped(&t_reflection, -0.8)},// Window_Glass + //{ 8, Material().diffuse({1.0, 1.0, 1.0})},// Material + { 9, Material().diffuse(vec3(1.0)).emissive(vec3(0.2)).specular(vec3(0.4), 70).reflection_mapped(&t_reflection, -1.0)},// Glossy_metal + //{10, Material().diffuse({1.0, 1.0, 1.0})},// Rogh_Metal +// {11, Material().no_colors().reflection_mapped(&t_reflection, 1.0)},// License_Plate_Metal + {11, Material().no_colors().reflection_mapped(&t_reflection, 1.0)},// License_Plate_Metal + //{12, Material().diffuse({1.0, 1.0, 1.0})},// License_Plate_Frame + //{13, Material().diffuse({1.0, 1.0, 1.0})},// }); + //carNode->setMaterial(Material().reflection_mapped(&t_reflection, 0.0).no_colors().no_texture_reset(), true); carNode->position = {500, 500, 100}; carNode->scale *= 100; rootNode->children.push_back(carNode); @@ -293,6 +295,8 @@ void updateFrame(GLFWwindow* window, int windowWidth, int windowHeight) { plainNode->uvOffset.y -= timeDelta*0.5; if (boxNode) boxNode->rotation.z += timeDelta; lightNode[1]->rotation.z -= timeDelta; + lightNode[1]->position.z = 80 + 40*glm::sin(5 * lightNode[1]->rotation.z); + //if(carNode) carNode->rotation.z += timeDelta; } diff --git a/src/sceneGraph.hpp b/src/sceneGraph.hpp index e579955..4c90eb8 100644 --- a/src/sceneGraph.hpp +++ b/src/sceneGraph.hpp @@ -14,6 +14,7 @@ #include #include #include +#include #include using glm::vec2; diff --git a/src/utilities/material.cpp b/src/utilities/material.cpp new file mode 100644 index 0000000..21937d5 --- /dev/null +++ b/src/utilities/material.cpp @@ -0,0 +1,104 @@ +#include +#include "material.hpp" +#include "imageLoader.hpp" + +Material Material::apply(const Material& other) const { + Material out(*this); + + if (!other.ignore_diffuse) out.diffuse_color = other.diffuse_color; + if (!other.ignore_emissive) out.emissive_color = other.emissive_color; + if (!other.ignore_specular) out.specular_color = other.specular_color; + if (!other.ignore_specular) out.shininess = other.shininess; + if (!other.ignore_diffuse) out.ignore_diffuse = false; + if (!other.ignore_emissive) out.ignore_emissive = false; + if (!other.ignore_specular) out.ignore_specular = false; + if (!other.texture_reset) out.texture_reset = true; + + if (other.texture_reset || other.diffuse_texture) out.diffuse_texture = other.diffuse_texture; + if (other.texture_reset || other.normal_texture) out.normal_texture = other.normal_texture; + if (other.texture_reset || other.displacement_texture) out.displacement_texture = other.displacement_texture; + if (other.texture_reset || other.reflection_texture) out.reflection_texture = other.reflection_texture; + if (other.texture_reset || other.reflection_texture) out.reflexiveness = other.reflexiveness; + + return out; +} + + +Material Material::diffuse(glm::vec3 color) const { + Material out(*this); + out.diffuse_color = color; + return out; +} +Material Material::specular(glm::vec3 color, float shininess) const { + Material out(*this); + out.specular_color = color; + out.shininess = shininess; + return out; +} +Material Material::emissive(glm::vec3 color) const { + Material out(*this); + out.emissive_color = color; + return out; +} +Material Material::textured(PNGImage* diffuse) const { + Material out(*this); + out.diffuse_texture = diffuse; + return out; +} +Material Material::normal_mapped(PNGImage* normal) const { + Material out(*this); + out.normal_texture = normal; + return out; +} +Material Material::diffuse_mapped(PNGImage* diffuse) const { + Material out(*this); + out.diffuse_texture = diffuse; + return out; +} +Material Material::displacement_mapped(PNGImage* displacement) const { + Material out(*this); + out.displacement_texture = displacement; + return out; +} +Material Material::reflection_mapped(PNGImage* reflection, float reflexiveness) const { + Material out(*this); + out.reflection_texture = reflection; + out.reflexiveness = reflexiveness; + return out; +} +Material Material::no_texture_reset() const { + Material out(*this); + out.texture_reset = false; + return out; +} +Material Material::no_colors() const { + Material out(*this); + out.ignore_diffuse = true; + out.ignore_emissive = true; + out.ignore_specular = true; + return out; +} +Material Material::no_diffuse() const { + Material out(*this); + out.ignore_diffuse = true; + return out; +} +Material Material::no_emissive() const { + Material out(*this); + out.ignore_emissive = true; + return out; +} +Material Material::no_specular() const { + Material out(*this); + out.ignore_specular = true; + return out; +} +Material Material::diffuse_only() const { + return this->no_emissive().no_specular(); +} +Material Material::emissive_only() const { + return this->no_diffuse().no_specular(); +} +Material Material::specular_only() const { + return this->no_diffuse().no_emissive(); +} diff --git a/src/utilities/material.hpp b/src/utilities/material.hpp new file mode 100644 index 0000000..1157fa7 --- /dev/null +++ b/src/utilities/material.hpp @@ -0,0 +1,43 @@ +#pragma once + +#include +#include "imageLoader.hpp" + +struct Material { + float opacity = 1.0; + float shininess = 1; // specular + float reflexiveness = 0; + glm::vec3 diffuse_color = glm::vec3(1.0); + glm::vec3 emissive_color = glm::vec3(0.5); + glm::vec3 specular_color = glm::vec3(0.2); + PNGImage* diffuse_texture = nullptr; + PNGImage* normal_texture = nullptr; + PNGImage* displacement_texture = nullptr; + PNGImage* reflection_texture = nullptr; + + bool ignore_diffuse = false; + bool ignore_emissive = false; + bool ignore_specular = false; + bool texture_reset = true; + + Material apply(const Material& other) const; + + Material diffuse(glm::vec3 color) const; + Material specular(glm::vec3 color, float shininess) const; + Material emissive(glm::vec3 color) const; + Material textured(PNGImage* diffuse) const; + Material normal_mapped(PNGImage* normal) const; + Material diffuse_mapped(PNGImage* diffuse) const; + Material displacement_mapped(PNGImage* displacement) const; + Material reflection_mapped(PNGImage* reflection, float reflexiveness) const; + + // avoid touching these: + Material no_texture_reset() const; + Material no_colors() const; // leave all colors alone + Material no_diffuse() const; + Material no_emissive() const; + Material no_specular() const; + Material diffuse_only() const; // and not the other two + Material emissive_only() const; // and not the other two + Material specular_only() const; // and not the other two +}; diff --git a/src/utilities/modelLoader.cpp b/src/utilities/modelLoader.cpp index b1495a1..58800f2 100644 --- a/src/utilities/modelLoader.cpp +++ b/src/utilities/modelLoader.cpp @@ -52,10 +52,7 @@ SceneNode* buildSceneNodes( out->children.push_back(mesh_node); uint meshidx = node->mMeshes[i]; - mesh_node->basecolor = mat_lookup[meshidx]->basecolor; - mesh_node->shininess = mat_lookup[meshidx]->shininess; - -// mesh_node.setTexture(&meshes[node->mMeshes[i]]); + mesh_node->setMaterial(*mat_lookup[meshidx]); mesh_node->setMesh(&meshes[meshidx]); } @@ -85,7 +82,7 @@ SceneNode* loadModelScene(const std::string& filename, const map& // read materials uint j=0; - Material default_material = Material::diffuse({1, 1, 1, 1}); + Material default_material = Material().diffuse({1, 1, 1}); vector materials(scene->mNumMaterials); for (Material& material : materials) { const aiMaterial* aimat = scene->mMaterials[j++]; @@ -98,21 +95,30 @@ SceneNode* loadModelScene(const std::string& filename, const map& cout << " " << aimat->mProperties[i]->mKey.C_Str() << endl; } - aiColor4D diffuse (1,1,1,1); - aimat->Get(AI_MATKEY_COLOR_DIFFUSE, diffuse); - //aiGetMaterialColor(aimat, "$mat.gltf.pbrMetallicRoughness.baseColorFactor", 0, 0, &diffuse); - //aiGetMaterialColor(aimat, "$mat.gltf.pbrMetallicRoughness.metallicFactor", 0, 0, &diffuse); - //aiGetMaterialColor(aimat, "$mat.gltf.pbrMetallicRoughness.roughnessFactor", 0, 0, &diffuse); - material.basecolor = {diffuse.r, diffuse.g, diffuse.b, diffuse.a}; + aiColor3D color (1,1,1); + aiColor4D color4 (1,1,1,0); + if (AI_SUCCESS == aimat->Get(AI_MATKEY_COLOR_DIFFUSE, color)) + material.diffuse_color = {color.r, color.g, color.b}; + if (AI_SUCCESS == aimat->Get(AI_MATKEY_COLOR_EMISSIVE, color)) + material.emissive_color = {color.r, color.g, color.b}; + if (AI_SUCCESS == aimat->Get(AI_MATKEY_COLOR_SPECULAR, color)) + material.specular_color = {color.r, color.g, color.b}; + //if (AI_SUCCESS == aiGetMaterialColor(aimat, "$mat.gltf.pbrMetallicRoughness.baseColorFactor", 0, 0, &color4)) + // material.diffuse_color = {color4.r, color4.g, color4.b}; + //if (AI_SUCCESS == aiGetMaterialColor(aimat, "$mat.gltf.pbrMetallicRoughness.metallicFactor", 0, 0, &color4)) + // material.emissive_color *= vec3{color4.r, color4.g, color4.b}; + //if (AI_SUCCESS == aiGetMaterialColor(aimat, "$mat.gltf.pbrMetallicRoughness.roughnessFactor", 0, 0, &color4)) + // material.specular_color = {color4.r, color4.g, color4.b}; aimat->Get(AI_MATKEY_SHININESS, material.shininess); } - for (auto override : overrides) - ((override.first>=0) + for (auto override : overrides) { + Material& mat = (override.first>=0) ? materials[override.first] - : default_material - ) = override.second; + : default_material; + mat = mat.apply(override.second); + } vector meshes( scene->mNumMeshes); vector textures(scene->mNumTextures); @@ -135,7 +141,7 @@ SceneNode* loadModelScene(const std::string& filename, const map& }); } - mat_lookup[j-1] = (aimesh->mMaterialIndex) + mat_lookup[j-1] = (aimesh->mMaterialIndex < meshes.size()) ? &materials[aimesh->mMaterialIndex] : &default_material; diff --git a/src/utilities/modelLoader.hpp b/src/utilities/modelLoader.hpp index dc70b6d..6dd2fa2 100644 --- a/src/utilities/modelLoader.hpp +++ b/src/utilities/modelLoader.hpp @@ -1,24 +1,12 @@ #pragma once #include "../sceneGraph.hpp" +#include "material.hpp" #include #include #define DEBUG false -struct Material { - vec4 basecolor; - float shininess = 10; - int texture_id = -1; - - static Material diffuse(vec4 color, float shininess = 10){ - Material out; - out.basecolor = color; - out.shininess = shininess; - return out; - } -}; - SceneNode* loadModelScene( const std::string& filename, const std::map& overrides={});