100 lines
2.7 KiB
C++
100 lines
2.7 KiB
C++
#include "material.h"
|
|
|
|
#include "../lib/glm/glm.hpp"
|
|
#include "../lib/glm/gtc/matrix_transform.hpp"
|
|
|
|
#include "light.h"
|
|
#include "shader.h"
|
|
#include "state.h"
|
|
#include "texture.h"
|
|
|
|
Material::Material(const std::shared_ptr<Texture>& tex,
|
|
const std::shared_ptr<Shader>& shader)
|
|
: shader_(shader)
|
|
, texture_(tex)
|
|
, color_(1.0f, 1.0f, 1.0f, 1.0f)
|
|
, shininess_(0)
|
|
{
|
|
}
|
|
|
|
const std::shared_ptr<Shader>& Material::shader() const
|
|
{
|
|
return shader_ ? shader_ : state::default_shader;
|
|
}
|
|
|
|
std::shared_ptr<Shader>& Material::shader()
|
|
{
|
|
return shader_ ? shader_ : state::default_shader;
|
|
}
|
|
|
|
void Material::set_shader(const std::shared_ptr<Shader>& shader)
|
|
{
|
|
shader_ = shader;
|
|
}
|
|
|
|
void Material::prepare()
|
|
{
|
|
// Activate shader
|
|
std::shared_ptr<Shader> active_shader = shader();
|
|
if (!active_shader)
|
|
return;
|
|
|
|
active_shader->use();
|
|
|
|
// Set uniform variables
|
|
const glm::mat4 mvp =
|
|
state::projection_matrix * state::view_matrix * state::model_matrix;
|
|
const int mvp_loc = active_shader->uniform_location("mvp");
|
|
Shader::set_mat4(mvp_loc, mvp);
|
|
|
|
// Set ModelView matrix
|
|
const glm::mat4 model_view = state::view_matrix * state::model_matrix;
|
|
const int model_view_loc = active_shader->uniform_location("modelView");
|
|
Shader::set_mat4(model_view_loc, model_view);
|
|
|
|
// Set Normal matrix (transpose of inverse of ModelView)
|
|
const glm::mat4 normal_matrix =
|
|
glm::transpose(glm::inverse(model_view));
|
|
const int normal_matrix_loc =
|
|
active_shader->uniform_location("normalMatrix");
|
|
Shader::set_mat4(normal_matrix_loc, normal_matrix);
|
|
|
|
// Set material properties
|
|
const int material_color_loc =
|
|
active_shader->uniform_location("materialColor");
|
|
Shader::set_vec4(material_color_loc, color_);
|
|
|
|
const int shininess_loc = active_shader->uniform_location("shininess");
|
|
Shader::set_float(shininess_loc, static_cast<float>(shininess_));
|
|
|
|
// Set ambient light
|
|
const int ambient_loc = active_shader->uniform_location("ambientLight");
|
|
Shader::set_vec3(ambient_loc, state::ambient);
|
|
|
|
// Set number of lights
|
|
const int num_lights_loc = active_shader->uniform_location("numLights");
|
|
Shader::set_int(num_lights_loc, static_cast<int>(state::lights.size()));
|
|
|
|
// Prepare each light
|
|
for (size_t i = 0; i < state::lights.size(); ++i) {
|
|
state::lights[i]->prepare(static_cast<int>(i), active_shader);
|
|
}
|
|
|
|
// Set texture-related uniforms
|
|
const int use_texture_loc =
|
|
active_shader->uniform_location("useTexture");
|
|
if (texture_) {
|
|
Shader::set_int(use_texture_loc, 1);
|
|
const int sampler_loc =
|
|
active_shader->uniform_location("texSampler");
|
|
Shader::set_int(sampler_loc, 0); // Texture unit 0
|
|
} else {
|
|
Shader::set_int(use_texture_loc, 0);
|
|
}
|
|
|
|
// Bind texture if available
|
|
if (texture_) {
|
|
texture_->bind();
|
|
}
|
|
}
|