Improve material loading and add coordinate system model

This commit is contained in:
Mario Hüttel 2020-03-26 22:57:08 +01:00
parent 4893a36197
commit 251adef6b5
16 changed files with 308 additions and 47 deletions

View File

@ -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"

View File

@ -0,0 +1,47 @@
#ifndef MATERIAL_H
#define MATERIAL_H
#include <opengl-playground/opengltexture.hpp>
#include <memory>
#include <vector>
#include <glm/glm.hpp>
class Material
{
public:
Material();
Material(std::shared_ptr<OpenGlTexture> diffuse_texture,
std::shared_ptr<OpenGlTexture> ambient_texture,
std::shared_ptr<OpenGlTexture> 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<OpenGlTexture> texture);
void pushAmbientTexture(std::shared_ptr<OpenGlTexture> texture);
void pushDiffuseTexture(std::shared_ptr<OpenGlTexture> texture);
void pushSpecularTexture(const std::vector<std::shared_ptr<OpenGlTexture>> &textures);
void pushAmbientTexture(const std::vector<std::shared_ptr<OpenGlTexture>> &textures);
void pushDiffuseTexture(const std::vector<std::shared_ptr<OpenGlTexture>> &textures);
const std::vector<std::shared_ptr<OpenGlTexture>> &getSpecularTextures();
const std::vector<std::shared_ptr<OpenGlTexture>> &getAmbientTextures();
const std::vector<std::shared_ptr<OpenGlTexture>> &getDiffuseTextures();
const glm::vec3 &getDiffuseColor();
const glm::vec3 &getAmbientColor();
const glm::vec3 &getSpecularColor();
float shininess_strength;
float shininess;
private:
std::vector<std::shared_ptr<OpenGlTexture>> diffuse_textures;
std::vector<std::shared_ptr<OpenGlTexture>> ambient_textures;
std::vector<std::shared_ptr<OpenGlTexture>> specular_textures;
glm::vec3 diff_color;
glm::vec3 ambient_color;
glm::vec3 specular_color;
};
#endif // MATERIAL_H

View File

@ -6,16 +6,17 @@
#include <opengl-playground/vertex.hpp>
#include <opengl-playground/opengltexture.hpp>
#include <opengl-playground/openglgraphics.hpp>
#include <opengl-playground/material.hpp>
class Mesh : public OpenGlGraphics
{
public:
Mesh(std::vector<Vertex> vertices, std::vector<unsigned int> indices,
std::vector<std::shared_ptr<OpenGlTexture>> textures,
const Material &mat,
std::shared_ptr<OpenGlShaderProgram> shader);
std::vector<Vertex> vertices;
std::vector<unsigned int> indices;
std::vector<std::shared_ptr<OpenGlTexture>> textures;
Material material;
void realize();
void render();
void render(const glm::mat4 &model_matrix, const glm::mat4 &normal_matrix);

View File

@ -22,7 +22,7 @@ class Model : public OpenGlGraphics
std::vector<Mesh> meshes;
std::vector<std::shared_ptr<OpenGlTexture>> allocated_textures;
std::string directory;
std::vector<std::shared_ptr<OpenGlTexture>> loadMaterialTextures(aiMaterial *mat, aiTextureType type, TextureType tex_type);
std::vector<std::shared_ptr<OpenGlTexture>> loadMaterialTextures(aiMaterial *mat, aiTextureType type);
void processNode(aiNode *node, const aiScene *scene);
Mesh processMesh(aiMesh *mesh, const aiScene *scene);
};

View File

@ -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;

View File

@ -4,12 +4,10 @@
#include <epoxy/gl.h>
#include <string>
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;

Binary file not shown.

Binary file not shown.

View File

@ -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

View File

@ -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);

View File

@ -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;

95
src/material.cpp Normal file
View File

@ -0,0 +1,95 @@
#include <opengl-playground/material.hpp>
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<OpenGlTexture> texture)
{
this->specular_textures.push_back(texture);
}
void Material::pushAmbientTexture(std::shared_ptr<OpenGlTexture> texture)
{
this->ambient_textures.push_back(texture);
}
void Material::pushDiffuseTexture(std::shared_ptr<OpenGlTexture> texture)
{
this->diffuse_textures.push_back(texture);
}
void Material::pushSpecularTexture(const std::vector<std::shared_ptr<OpenGlTexture>> &textures)
{
this->specular_textures.insert(this->specular_textures.end(), textures.begin(), textures.end());
}
void Material::pushAmbientTexture(const std::vector<std::shared_ptr<OpenGlTexture>> &textures)
{
this->ambient_textures.insert(this->ambient_textures.end(), textures.begin(), textures.end());
}
void Material::pushDiffuseTexture(const std::vector<std::shared_ptr<OpenGlTexture>> &textures)
{
this->diffuse_textures.insert(this->diffuse_textures.end(), textures.begin(), textures.end());
}
const std::vector<std::shared_ptr<OpenGlTexture>> &Material::getSpecularTextures()
{
return this->specular_textures;
}
const std::vector<std::shared_ptr<OpenGlTexture>> &Material::getAmbientTextures()
{
return this->ambient_textures;
}
const std::vector<std::shared_ptr<OpenGlTexture>> &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;
}

View File

@ -1,17 +1,16 @@
#include <opengl-playground/mesh.hpp>
#include <opengl-playground/globalcanvassettings.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <iostream>
Mesh::Mesh(std::vector<Vertex> vertices, std::vector<unsigned int> indices,
std::vector<std::shared_ptr<OpenGlTexture> > textures,
const Material &mat,
std::shared_ptr<OpenGlShaderProgram> 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);

View File

@ -1,4 +1,5 @@
#include <opengl-playground/model.hpp>
#include <opengl-playground/material.hpp>
#include <iostream>
Model::Model(const std::string &path, const glm::vec4 &static_color, std::shared_ptr<OpenGlShaderProgram> shader)
@ -47,8 +48,7 @@ void Model::processNode(aiNode *node, const aiScene *scene)
}
std::vector<std::shared_ptr<OpenGlTexture>> Model::loadMaterialTextures(aiMaterial *mat, aiTextureType type,
TextureType tex_type)
std::vector<std::shared_ptr<OpenGlTexture>> Model::loadMaterialTextures(aiMaterial *mat, aiTextureType type)
{
std::vector<std::shared_ptr<OpenGlTexture>> tex_vector;
@ -66,7 +66,7 @@ std::vector<std::shared_ptr<OpenGlTexture>> Model::loadMaterialTextures(aiMateri
}
if (!already_loaded) {
auto new_texture = std::make_shared<OpenGlTexture>(tex_type, str.C_Str());
auto new_texture = std::make_shared<OpenGlTexture>(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<Vertex> vertices;
std::vector<unsigned int> indices;
std::vector<std::shared_ptr<OpenGlTexture>> 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;
}

View File

@ -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)

View File

@ -4,7 +4,7 @@
#include <stb/stb_image.h>
#include <iostream>
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;
}