diff --git a/CMakeLists.txt b/CMakeLists.txt index 01056ba..5651b51 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ project(opengl-playground) #set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 3.16) find_package(glm REQUIRED) find_package(PkgConfig REQUIRED) pkg_check_modules(EPOXY REQUIRED epoxy) @@ -26,6 +26,10 @@ configure_file("shaders/2d-zoom-translate-vertex.glsl" "shaders/2d-zoom-translat configure_file("shaders/mesh-vertex.glsl" "shaders/mesh-vertex.glsl" COPYONLY) configure_file("shaders/mesh-fragment.glsl" "shaders/mesh-fragment.glsl" COPYONLY) +configure_file("models/coordinate-system/coordsys.obj" "coordinate-system/coordsys.obj" COPYONLY) +configure_file("models/coordinate-system/coordsys.mtl" "coordinate-system/coordsys.mtl" COPYONLY) + + set(IMGUI_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/imgui-submodule/imgui/imgui.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/imgui-submodule/imgui/imgui_draw.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/imgui-submodule/imgui/imgui_demo.cpp" diff --git a/include/opengl-playground/material.hpp b/include/opengl-playground/material.hpp new file mode 100644 index 0000000..c9cf785 --- /dev/null +++ b/include/opengl-playground/material.hpp @@ -0,0 +1,47 @@ +#ifndef MATERIAL_H +#define MATERIAL_H + +#include +#include +#include +#include + + +class Material +{ + public: + Material(); + Material(std::shared_ptr diffuse_texture, + std::shared_ptr ambient_texture, + std::shared_ptr specular_texture); + Material(const glm::vec3 &diff_color, const glm::vec3 &ambient_color, const glm::vec3 &specular_color); + void setSpecularColor(const glm::vec3 &color); + void setAmbientColor(const glm::vec3 &color); + void setDiffuseColor(const glm::vec3 &color); + void pushSpecularTexture(std::shared_ptr texture); + void pushAmbientTexture(std::shared_ptr texture); + void pushDiffuseTexture(std::shared_ptr texture); + void pushSpecularTexture(const std::vector> &textures); + void pushAmbientTexture(const std::vector> &textures); + void pushDiffuseTexture(const std::vector> &textures); + + const std::vector> &getSpecularTextures(); + const std::vector> &getAmbientTextures(); + const std::vector> &getDiffuseTextures(); + const glm::vec3 &getDiffuseColor(); + const glm::vec3 &getAmbientColor(); + const glm::vec3 &getSpecularColor(); + + float shininess_strength; + float shininess; + + private: + std::vector> diffuse_textures; + std::vector> ambient_textures; + std::vector> specular_textures; + glm::vec3 diff_color; + glm::vec3 ambient_color; + glm::vec3 specular_color; +}; + +#endif // MATERIAL_H diff --git a/include/opengl-playground/mesh.hpp b/include/opengl-playground/mesh.hpp index 20b4339..9172cf9 100644 --- a/include/opengl-playground/mesh.hpp +++ b/include/opengl-playground/mesh.hpp @@ -6,16 +6,17 @@ #include #include #include +#include class Mesh : public OpenGlGraphics { public: Mesh(std::vector vertices, std::vector indices, - std::vector> textures, + const Material &mat, std::shared_ptr shader); std::vector vertices; std::vector indices; - std::vector> textures; + Material material; void realize(); void render(); void render(const glm::mat4 &model_matrix, const glm::mat4 &normal_matrix); diff --git a/include/opengl-playground/model.hpp b/include/opengl-playground/model.hpp index 5d462ff..837561b 100644 --- a/include/opengl-playground/model.hpp +++ b/include/opengl-playground/model.hpp @@ -22,7 +22,7 @@ class Model : public OpenGlGraphics std::vector meshes; std::vector> allocated_textures; std::string directory; - std::vector> loadMaterialTextures(aiMaterial *mat, aiTextureType type, TextureType tex_type); + std::vector> loadMaterialTextures(aiMaterial *mat, aiTextureType type); void processNode(aiNode *node, const aiScene *scene); Mesh processMesh(aiMesh *mesh, const aiScene *scene); }; diff --git a/include/opengl-playground/openglshader.hpp b/include/opengl-playground/openglshader.hpp index 5adeefa..e217ee3 100644 --- a/include/opengl-playground/openglshader.hpp +++ b/include/opengl-playground/openglshader.hpp @@ -22,6 +22,7 @@ class OpenGlShaderProgram void setUniformVec3(const std::string &uniform, const glm::vec3 &vector); void setUniformMat4(const std::string &uniform, const glm::mat4 &matrix); void setUniformVec4(const std::string &uniform, const glm::vec4 &vector); + void setUniformBool(const std::string &uniform, bool value); private: bool compiled; GLuint shader_program; diff --git a/include/opengl-playground/opengltexture.hpp b/include/opengl-playground/opengltexture.hpp index c3934b7..8a149b7 100644 --- a/include/opengl-playground/opengltexture.hpp +++ b/include/opengl-playground/opengltexture.hpp @@ -4,12 +4,10 @@ #include #include -typedef enum {TEXTURE_DIFFUSE, TEXTURE_SPECULAR} TextureType; - class OpenGlTexture { public: - OpenGlTexture(TextureType type, const std::string &texture_path); + OpenGlTexture(const std::string &texture_path); OpenGlTexture(); OpenGlTexture(const OpenGlTexture &tex) = delete; OpenGlTexture(const OpenGlTexture &&tex) = delete; @@ -19,12 +17,10 @@ class OpenGlTexture void use(unsigned int slot); void use(); const std::string &getPath(); - TextureType getType(); + float blend; private: std::string texture_path; - TextureType type; - protected: GLuint texture; diff --git a/models/coordinate-system/coords.blend b/models/coordinate-system/coords.blend new file mode 100644 index 0000000..e6232c4 Binary files /dev/null and b/models/coordinate-system/coords.blend differ diff --git a/models/coordinate-system/coords.blend1 b/models/coordinate-system/coords.blend1 new file mode 100644 index 0000000..e96bb89 Binary files /dev/null and b/models/coordinate-system/coords.blend1 differ diff --git a/models/coordinate-system/coordsys.mtl b/models/coordinate-system/coordsys.mtl new file mode 100644 index 0000000..0477e93 --- /dev/null +++ b/models/coordinate-system/coordsys.mtl @@ -0,0 +1,32 @@ +# Blender MTL File: 'coords.blend' +# Material Count: 3 + +newmtl Materialx +Ns 323.999994 +Ka 1.000000 1.000000 1.000000 +Kd 0.800000 0.000000 0.002609 +Ks 0.216667 0.216667 0.216667 +Ke 0.000000 0.000000 0.000000 +Ni 1.450000 +d 1.000000 +illum 2 + +newmtl Materialy +Ns 225.000000 +Ka 1.000000 1.000000 1.000000 +Kd 0.004587 0.800000 0.000000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.450000 +d 1.000000 +illum 2 + +newmtl Materialz +Ns 225.000000 +Ka 1.000000 1.000000 1.000000 +Kd 0.000000 0.003199 0.800000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.450000 +d 1.000000 +illum 2 diff --git a/shaders/mesh-fragment.glsl b/shaders/mesh-fragment.glsl index d4a655c..1d6e3b8 100644 --- a/shaders/mesh-fragment.glsl +++ b/shaders/mesh-fragment.glsl @@ -9,6 +9,14 @@ struct Material { sampler2D specular1; sampler2D specular2; sampler2D specular3; + sampler2D ambient0; + sampler2D ambient1; + bool use_diff_color; + vec3 diff_color; + bool use_spec_color; + vec3 spec_color; + int use_amb_color; + vec3 amb_color; }; out vec4 fragmentColor; @@ -26,8 +34,28 @@ void main() const float light_spec = 0.4; const float light_diff = 0.7; - vec3 diffuseTexCol = vec3(texture(material.diffuse0, TexCoord)); - vec3 specularTexCol = vec3(texture(material.specular0, TexCoord)); + vec3 diffuseTexCol; + if (material.use_diff_color) { + diffuseTexCol = material.diff_color; + } else { + diffuseTexCol = vec3(texture(material.diffuse0, TexCoord)); + } + + vec3 specularTexCol; + if (material.use_spec_color) { + specularTexCol = material.spec_color; + } else { + specularTexCol = vec3(texture(material.specular0, TexCoord)); + } + + vec3 ambTexCol; + if (material.use_amb_color == 0) { + ambTexCol = vec3(texture(material.ambient0, TexCoord)); + } else if (material.use_amb_color == 1) { + ambTexCol = diffuseTexCol * 0.5; + } else if (material.use_amb_color == 2) { + ambTexCol = material.amb_color; + } vec3 normal_n = normalize(Normal); vec3 light_dir_n = normalize(light_direction); diff --git a/src/main.cpp b/src/main.cpp index 54a4668..767a3f3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -59,6 +59,9 @@ int main(int argc, char **argv) shader->compile(); Model m("nanosuit/nanosuit.obj", glm::vec4(1.0f, 0.0f, 0.0f, 1.0f), shader); + Model coords("coordinate-system/coordsys.obj", glm::vec4(1.0f, 0.0f, 0.0f, 1.0f), shader); + + coords.realize(); m.realize(); m.setModelMatrix(glm::scale(glm::mat4(1.0f), glm::vec3(0.2f, 0.2f, 0.2f))); @@ -159,6 +162,7 @@ int main(int argc, char **argv) } m.render(); + coords.render(); glm::mat4 current_model_matrix = m.getModelMatrix(); current_model_matrix = glm::translate(glm::mat4(1.0f), glm::vec3(3.0f, 0.0f, 0.0f)) * current_model_matrix; diff --git a/src/material.cpp b/src/material.cpp new file mode 100644 index 0000000..35c65d2 --- /dev/null +++ b/src/material.cpp @@ -0,0 +1,95 @@ +#include + + + +Material::Material() +{ + shininess_strength = 0.0f; + shininess = 1.0f; + this->setDiffuseColor(glm::vec3(0.0f)); + this->setAmbientColor(glm::vec3(0.0f)); + this->setSpecularColor(glm::vec3(0.0f)); +} + +Material::Material(const glm::vec3 &diff_color, const glm::vec3 &ambient_color, const glm::vec3 &specular_color) : Material() +{ + this->setDiffuseColor(diff_color); + this->setAmbientColor(ambient_color); + this->setSpecularColor(specular_color); +} + +void Material::setSpecularColor(const glm::vec3 &color) +{ + this->specular_color = color; +} + +void Material::setAmbientColor(const glm::vec3 &color) +{ + this->ambient_color = color; +} + +void Material::setDiffuseColor(const glm::vec3 &color) +{ + this->diff_color = color; +} + +void Material::pushSpecularTexture(std::shared_ptr texture) +{ + this->specular_textures.push_back(texture); +} + +void Material::pushAmbientTexture(std::shared_ptr texture) +{ + this->ambient_textures.push_back(texture); +} + +void Material::pushDiffuseTexture(std::shared_ptr texture) +{ + this->diffuse_textures.push_back(texture); +} + +void Material::pushSpecularTexture(const std::vector> &textures) +{ + this->specular_textures.insert(this->specular_textures.end(), textures.begin(), textures.end()); +} + +void Material::pushAmbientTexture(const std::vector> &textures) +{ + this->ambient_textures.insert(this->ambient_textures.end(), textures.begin(), textures.end()); +} + +void Material::pushDiffuseTexture(const std::vector> &textures) +{ + this->diffuse_textures.insert(this->diffuse_textures.end(), textures.begin(), textures.end()); +} + +const std::vector> &Material::getSpecularTextures() +{ + return this->specular_textures; +} + +const std::vector> &Material::getAmbientTextures() +{ + return this->ambient_textures; +} + +const std::vector> &Material::getDiffuseTextures() +{ + return this->diffuse_textures; +} + +const glm::vec3 &Material::getDiffuseColor() +{ + return this->diff_color; +} + +const glm::vec3 &Material::getAmbientColor() +{ + return this->ambient_color; +} + +const glm::vec3 &Material::getSpecularColor() +{ + return this->specular_color; +} + diff --git a/src/mesh.cpp b/src/mesh.cpp index d44094a..e8822d1 100644 --- a/src/mesh.cpp +++ b/src/mesh.cpp @@ -1,17 +1,16 @@ #include #include - #include #include Mesh::Mesh(std::vector vertices, std::vector indices, - std::vector > textures, + const Material &mat, std::shared_ptr shader) : OpenGlGraphics(shader) { this->vertices = vertices; this->indices = indices; - this->textures = textures; + this->material = mat; } void Mesh::realize() @@ -52,24 +51,62 @@ void Mesh::render(const glm::mat4 &model_matrix, const glm::mat4 &normal_matrix) this->shaderprog->setUniformMat4("projection_view_matrix", GlobalCanvasSettings::getPVMatrix()); this->shaderprog->setUniformVec3("camera_position", GlobalCanvasSettings::getCameraPosition()); - int spec_num = 0; - int diff_num = 0; + auto diffTex = this->material.getDiffuseTextures(); + auto specTex = this->material.getSpecularTextures(); + auto ambTex = this->material.getAmbientTextures(); + /* Setup the texture samplers */ - for (unsigned int i = 0; i < this->textures.size(); i++) { + int tex_slot = 0; + for (unsigned int i = 0; i < diffTex.size(); i++, tex_slot++) { std::string uniform_name; - textures[i]->use(i); - switch (textures[i]->getType()) { - case TEXTURE_DIFFUSE: - uniform_name = "material.diffuse" + std::to_string(diff_num++); - this->shaderprog->setUniformInt(uniform_name, i); - break; - case TEXTURE_SPECULAR: - uniform_name = "material.specular" + std::to_string(spec_num++); - this->shaderprog->setUniformInt(uniform_name, i); - break; - default: - break; - } + diffTex[i]->use(tex_slot); + uniform_name = "material.diffuse" + std::to_string(i); + this->shaderprog->setUniformInt(uniform_name, i); + } + + for (unsigned int i = 0; i < specTex.size(); i++, tex_slot++) { + std::string uniform_name; + specTex[i]->use(tex_slot); + uniform_name = "material.specular" + std::to_string(i); + this->shaderprog->setUniformInt(uniform_name, i); + } + + for (unsigned int i = 0; i < ambTex.size(); i++, tex_slot++) { + std::string uniform_name; + specTex[i]->use(tex_slot); + uniform_name = "material.ambient" + std::to_string(i); + this->shaderprog->setUniformInt(uniform_name, i); + } + + if (diffTex.size() == 0) { + this->shaderprog->setUniformVec3("material.diff_color", this->material.getDiffuseColor()); + this->shaderprog->setUniformBool("material.use_diff_color", true); + } else { + this->shaderprog->setUniformBool("material.use_diff_color", false); + } + + if (specTex.size() == 0) { + this->shaderprog->setUniformVec3("material.spec_color", this->material.getSpecularColor()); + this->shaderprog->setUniformBool("material.use_spec_color", true); + } else { + this->shaderprog->setUniformBool("material.use_spec_color", false); + } + + if (specTex.size() == 0) { + this->shaderprog->setUniformVec3("material.spec_color", this->material.getSpecularColor()); + this->shaderprog->setUniformBool("material.use_spec_color", true); + } else { + this->shaderprog->setUniformBool("material.use_spec_color", false); + } + + if (diffTex.size() == 0 && ambTex.size() == 0) { + this->shaderprog->setUniformVec3("material.amb_color", this->material.getAmbientColor()); + this->shaderprog->setUniformInt("material.use_amb_color", 2); + } else { + if (diffTex.size() > 0) + this->shaderprog->setUniformInt("material.use_amb_color", 1); + else + this->shaderprog->setUniformInt("material.use_amb_color", 0); } glBindVertexArray(this->vao); diff --git a/src/model.cpp b/src/model.cpp index 61f3a6f..49c2b41 100644 --- a/src/model.cpp +++ b/src/model.cpp @@ -1,4 +1,5 @@ #include +#include #include Model::Model(const std::string &path, const glm::vec4 &static_color, std::shared_ptr shader) @@ -47,8 +48,7 @@ void Model::processNode(aiNode *node, const aiScene *scene) } -std::vector> Model::loadMaterialTextures(aiMaterial *mat, aiTextureType type, - TextureType tex_type) +std::vector> Model::loadMaterialTextures(aiMaterial *mat, aiTextureType type) { std::vector> tex_vector; @@ -66,7 +66,7 @@ std::vector> Model::loadMaterialTextures(aiMateri } if (!already_loaded) { - auto new_texture = std::make_shared(tex_type, str.C_Str()); + auto new_texture = std::make_shared(str.C_Str()); new_texture->loadFromImagePath(this->directory); tex_vector.push_back(new_texture); this->allocated_textures.push_back(new_texture); @@ -80,7 +80,7 @@ Mesh Model::processMesh(aiMesh *mesh, const aiScene *scene) { std::vector vertices; std::vector indices; - std::vector> textures; + Material mesh_material; for(unsigned int i = 0; i < mesh->mNumVertices; i++) { @@ -115,15 +115,30 @@ Mesh Model::processMesh(aiMesh *mesh, const aiScene *scene) if(mesh->mMaterialIndex >= 0) { + aiColor3D col; + aiMaterial *material = scene->mMaterials[mesh->mMaterialIndex]; - auto diffuseTextures = loadMaterialTextures(material, aiTextureType_DIFFUSE, TEXTURE_DIFFUSE); - auto specularTextures = loadMaterialTextures(material, aiTextureType_SPECULAR, TEXTURE_SPECULAR); - textures.insert(textures.end(), diffuseTextures.begin(), diffuseTextures.end()); - textures.insert(textures.end(), specularTextures.begin(), specularTextures.end()); + auto diffuseTextures = loadMaterialTextures(material, aiTextureType_DIFFUSE); + auto specularTextures = loadMaterialTextures(material, aiTextureType_SPECULAR); + auto ambientTextures = loadMaterialTextures(material, aiTextureType_AMBIENT); + + mesh_material.pushDiffuseTexture(diffuseTextures); + mesh_material.pushSpecularTexture(specularTextures); + mesh_material.pushAmbientTexture(ambientTextures); + + if (!material->Get(AI_MATKEY_COLOR_AMBIENT, col)) + mesh_material.setAmbientColor(glm::vec3(col.r, col.g, col.b)); + if (!material->Get(AI_MATKEY_COLOR_SPECULAR, col)) + mesh_material.setSpecularColor(glm::vec3(col.r, col.g, col.b)); + if (!material->Get(AI_MATKEY_COLOR_DIFFUSE, col)) + mesh_material.setDiffuseColor(glm::vec3(col.r, col.g, col.b)); + + material->Get(AI_MATKEY_SHININESS, mesh_material.shininess); + material->Get(AI_MATKEY_SHININESS_STRENGTH, mesh_material.shininess_strength); } - Mesh my_mesh = Mesh(vertices, indices, textures, this->shaderprog); + Mesh my_mesh = Mesh(vertices, indices, mesh_material, this->shaderprog); my_mesh.realize(); return my_mesh; } diff --git a/src/openglshader.cpp b/src/openglshader.cpp index e503008..0b1c8ca 100644 --- a/src/openglshader.cpp +++ b/src/openglshader.cpp @@ -208,6 +208,11 @@ void OpenGlShaderProgram::setUniformVec4(const std::string &uniform, const glm:: } } +void OpenGlShaderProgram::setUniformBool(const std::string &uniform, bool value) +{ + this->setUniformInt(uniform, value ? 1 : 0); +} + int OpenGlShaderProgram::getUniformLoc(const std::string &uniform) { if (!this->compiled) diff --git a/src/opengltexture.cpp b/src/opengltexture.cpp index 0160e4c..5a5307c 100644 --- a/src/opengltexture.cpp +++ b/src/opengltexture.cpp @@ -4,7 +4,7 @@ #include #include -OpenGlTexture::OpenGlTexture(TextureType type, const std::string &texture_path) +OpenGlTexture::OpenGlTexture(const std::string &texture_path) { glGenTextures(1, &this->texture); glBindTexture(GL_TEXTURE_2D, this->texture); @@ -12,11 +12,11 @@ OpenGlTexture::OpenGlTexture(TextureType type, const std::string &texture_path) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - this->type = type; this->texture_path = texture_path; + this->blend = 1.0f; } -OpenGlTexture::OpenGlTexture() : OpenGlTexture(TEXTURE_DIFFUSE, "") +OpenGlTexture::OpenGlTexture() : OpenGlTexture("") { } @@ -79,7 +79,3 @@ const std::string &OpenGlTexture::getPath() return this->texture_path; } -TextureType OpenGlTexture::getType() -{ - return this->type; -}