Implement normal maps
This commit is contained in:
parent
dbc12e422c
commit
da3c56af36
|
@ -172,13 +172,14 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
// entity.add_component<se::ModelComponent>("examples/dev_testing/resources/viper/viper.obj");
|
// entity.add_component<se::ModelComponent>("examples/dev_testing/resources/viper/viper.obj");
|
||||||
// entity.add_component<se::ModelComponent>("examples/dev_testing/resources/halot/chief.fbx");
|
// entity.add_component<se::ModelComponent>("examples/dev_testing/resources/halot/chief.fbx");
|
||||||
entity.add_component<se::ModelComponent>("examples/dev_testing/resources/planks/planks.fbx");
|
//entity.add_component<se::ModelComponent>("examples/dev_testing/resources/planks/planks.fbx", simpleengine::gfx::ModelProcessingFlags::MdlProcFlag_CALCULATE_TANGENT_SPACE);
|
||||||
|
entity.add_component<se::ModelComponent>("examples/dev_testing/resources/bricks/bricks.fbx", simpleengine::gfx::ModelProcessingFlags::MdlProcFlag_CALCULATE_TANGENT_SPACE);
|
||||||
|
|
||||||
// entity.add_component<se::ModelComponent>("examples/dev_testing/resources/scientist/scientist.fbx");
|
// entity.add_component<se::ModelComponent>("examples/dev_testing/resources/scientist/scientist.fbx");
|
||||||
// entity.add_component<se::ModelComponent>("examples/dev_testing/resources/paradigm/paradigm.fbx");
|
// entity.add_component<se::ModelComponent>("examples/dev_testing/resources/paradigm/paradigm.fbx");
|
||||||
// entity.add_component<se::RotatingComponent>();
|
// entity.add_component<se::RotatingComponent>();
|
||||||
auto &transform_comp = entity.add_component<se::TransformComponent>();
|
auto &transform_comp = entity.add_component<se::TransformComponent>();
|
||||||
transform_comp.translate(7.f, -4.f, 0.f);
|
transform_comp.translate(7.f, 0.f, 0.f);
|
||||||
// transform_comp.scale(0.05f);
|
// transform_comp.scale(0.05f);
|
||||||
// transform_comp.rotate_z(-90.f);
|
// transform_comp.rotate_z(-90.f);
|
||||||
// transform_comp.rotate_y(-90.f);
|
// transform_comp.rotate_y(-90.f);
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "../renderable.h"
|
#include "../renderable.h"
|
||||||
#include "../transformable.h"
|
#include "../transformable.h"
|
||||||
#include "material.h"
|
#include "material.h"
|
||||||
|
#include "../vector.h"
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -23,14 +24,23 @@ namespace simpleengine::gfx {
|
||||||
std::vector<LitVertex> vertices;
|
std::vector<LitVertex> vertices;
|
||||||
std::vector<GLuint> indicies;
|
std::vector<GLuint> indicies;
|
||||||
|
|
||||||
|
std::vector<simpleengine::Vectorf> tangents;
|
||||||
|
std::vector<simpleengine::Vectorf> bitangents;
|
||||||
|
|
||||||
bool are_buffers_created = false;
|
bool are_buffers_created = false;
|
||||||
gfx::VBO ebo;
|
gfx::VBO ebo;
|
||||||
gfx::VBO vbo;
|
gfx::VBO vbo;
|
||||||
gfx::VAO vao;
|
gfx::VAO vao;
|
||||||
|
|
||||||
|
gfx::VBO tangent_vbo;
|
||||||
|
//gfx::VAO tangent_vao;
|
||||||
|
|
||||||
|
gfx::VBO bitangent_vbo;
|
||||||
|
//gfx::VAO bitangent_vao;
|
||||||
|
|
||||||
Mesh(std::vector<LitVertex> vertices, std::vector<GLuint> indicies, Material material);
|
Mesh(std::vector<LitVertex> vertices, std::vector<GLuint> indicies, Material material);
|
||||||
Mesh(std::vector<LitVertex> vertices, std::vector<GLuint> indicies = std::vector<GLuint>(), std::optional<Material> material = std::nullopt);
|
Mesh(std::vector<LitVertex> vertices, std::vector<GLuint> indicies = std::vector<GLuint>(), std::optional<Material> material = std::nullopt);
|
||||||
Mesh(std::vector<LitVertex> vertices, std::vector<GLuint> indicies, Material material, gfx::VBO ebo, gfx::VBO vbo, gfx::VAO vao);
|
Mesh(std::vector<LitVertex> vertices, std::vector<GLuint> indicies, Material material, gfx::VBO ebo, gfx::VBO vbo, gfx::VAO vao, gfx::VBO tangent_vbo, gfx::VBO bitangent_vbo);
|
||||||
|
|
||||||
virtual void destroy() override;
|
virtual void destroy() override;
|
||||||
|
|
||||||
|
@ -45,5 +55,12 @@ namespace simpleengine::gfx {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void calculate_normals();
|
void calculate_normals();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Calculate tangents and bi-tangents (tangent space) for the model.
|
||||||
|
*
|
||||||
|
* @note This **will** overwrite the existing tangents and bi-tangents.
|
||||||
|
*/
|
||||||
|
void calculate_tangents();
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "mesh.h"
|
#include "mesh.h"
|
||||||
#include "simpleengine/gfx/texture.h"
|
#include "simpleengine/gfx/texture.h"
|
||||||
|
#include "../vector.h"
|
||||||
|
|
||||||
#include <assimp/material.h>
|
#include <assimp/material.h>
|
||||||
#include <assimp/mesh.h>
|
#include <assimp/mesh.h>
|
||||||
|
@ -14,6 +15,7 @@ namespace simpleengine::gfx {
|
||||||
MdlProcFlag_NONE = 0b00000000,
|
MdlProcFlag_NONE = 0b00000000,
|
||||||
MdlProcFlag_FLIP_TEX_COORDS_VERTICALLY = 0b00000001,
|
MdlProcFlag_FLIP_TEX_COORDS_VERTICALLY = 0b00000001,
|
||||||
MdlProcFlag_FLIP_TEX_COORDS_HORIZONTALLY = 0b00000010,
|
MdlProcFlag_FLIP_TEX_COORDS_HORIZONTALLY = 0b00000010,
|
||||||
|
MdlProcFlag_CALCULATE_TANGENT_SPACE = 0b00000100,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -39,12 +41,12 @@ namespace simpleengine::gfx {
|
||||||
|
|
||||||
std::unordered_map<aiTextureType, std::vector<Texture>> load_all_textures(aiMaterial* material);
|
std::unordered_map<aiTextureType, std::vector<Texture>> load_all_textures(aiMaterial* material);
|
||||||
std::vector<std::shared_ptr<Texture>> load_material_texture(std::unordered_map<aiTextureType, std::vector<std::shared_ptr<Texture>>>& processed_textures, aiMaterial* material, aiTextureType type, TextureFlags texture_color);
|
std::vector<std::shared_ptr<Texture>> load_material_texture(std::unordered_map<aiTextureType, std::vector<std::shared_ptr<Texture>>>& processed_textures, aiMaterial* material, aiTextureType type, TextureFlags texture_color);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void post_process();
|
void post_process();
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void vertically_flip_tex_coords();
|
void vertically_flip_tex_coords();
|
||||||
void horizontally_flip_tex_coords();
|
void horizontally_flip_tex_coords();
|
||||||
|
void calculate_tangents();
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -51,6 +51,10 @@ namespace simpleengine::gfx {
|
||||||
glBindVertexArray(handle);
|
glBindVertexArray(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void unbind() const {
|
||||||
|
glBindVertexArray(0);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Fix this.
|
// TODO: Fix this.
|
||||||
void enable_attrib(const VBO& vbo, GLuint index, GLint size, GLenum type, GLsizei stride, size_t offset, bool should_bind = true) const {
|
void enable_attrib(const VBO& vbo, GLuint index, GLint size, GLenum type, GLsizei stride, size_t offset, bool should_bind = true) const {
|
||||||
if (should_bind) {
|
if (should_bind) {
|
||||||
|
|
|
@ -40,6 +40,10 @@ namespace simpleengine::gfx {
|
||||||
glBindBuffer(type, handle);
|
glBindBuffer(type, handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void unbind() const {
|
||||||
|
glBindBuffer(type, 0);
|
||||||
|
}
|
||||||
|
|
||||||
void buffer(void *data, size_t offset, size_t size) {
|
void buffer(void *data, size_t offset, size_t size) {
|
||||||
bind();
|
bind();
|
||||||
glBufferData(type, size - offset, data, dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
|
glBufferData(type, size - offset, data, dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
|
||||||
|
|
|
@ -12,6 +12,11 @@ in vec3 vs_view_pos;
|
||||||
in vec3 vs_light_pos;
|
in vec3 vs_light_pos;
|
||||||
in vec3 vs_frag_pos;
|
in vec3 vs_frag_pos;
|
||||||
|
|
||||||
|
in mat3 vs_tbn;
|
||||||
|
|
||||||
|
in vec3 vs_tangent;
|
||||||
|
in vec3 vs_bitangent;
|
||||||
|
|
||||||
const int SAMP_DIFFUSE = 0;
|
const int SAMP_DIFFUSE = 0;
|
||||||
const int SAMP_SPECULAR = 1;
|
const int SAMP_SPECULAR = 1;
|
||||||
|
|
||||||
|
@ -21,6 +26,9 @@ struct Material {
|
||||||
bool has_specular_map;
|
bool has_specular_map;
|
||||||
sampler2D specular_map;
|
sampler2D specular_map;
|
||||||
|
|
||||||
|
// TODO: Make Optional
|
||||||
|
sampler2D normal_map;
|
||||||
|
|
||||||
float ambient_strength;
|
float ambient_strength;
|
||||||
float diffuse_strength;
|
float diffuse_strength;
|
||||||
float specular_strength;
|
float specular_strength;
|
||||||
|
@ -37,14 +45,12 @@ out vec4 fs_color;
|
||||||
vec3 calculate_lighting();
|
vec3 calculate_lighting();
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
|
||||||
|
|
||||||
// Combine diffuse lighting, specular, and the texture into one color.
|
|
||||||
//fs_color = vec4(diffuse, 1.f) * texture(u_material.diffuse, vs_texcoord) + vec4(final_specular, 1.f);
|
|
||||||
|
|
||||||
vec3 lighting = calculate_lighting();
|
vec3 lighting = calculate_lighting();
|
||||||
|
|
||||||
|
|
||||||
fs_color = vec4(lighting, 1.f) * texture(u_material.diffuse, vs_texcoord);
|
fs_color = vec4(lighting, 1.f) * texture(u_material.diffuse, vs_texcoord);
|
||||||
|
//fs_color = vec4(vs_tangent, 1.f);
|
||||||
|
//fs_color = vec4(vs_bitangent, 1.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 calculate_lighting() {
|
vec3 calculate_lighting() {
|
||||||
|
@ -52,8 +58,14 @@ vec3 calculate_lighting() {
|
||||||
//float ambient_strength = 0.1;
|
//float ambient_strength = 0.1;
|
||||||
vec3 ambient = u_material.ambient_strength * u_light_color;
|
vec3 ambient = u_material.ambient_strength * u_light_color;
|
||||||
|
|
||||||
|
// Apply the normal map to the lighting.
|
||||||
|
vec3 normal = vs_normal;
|
||||||
|
normal = texture(u_material.normal_map, vs_texcoord).rgb;
|
||||||
|
normal = normal * 2.0 - 1.0;
|
||||||
|
normal = normalize(vs_tbn * normal);
|
||||||
|
|
||||||
// Diffuse
|
// Diffuse
|
||||||
vec3 norm = normalize(vs_world_normal);
|
vec3 norm = normalize(normal);
|
||||||
vec3 light_dir = normalize(vs_light_pos - vs_frag_pos);
|
vec3 light_dir = normalize(vs_light_pos - vs_frag_pos);
|
||||||
float diff = max(dot(norm, light_dir), 0.f);
|
float diff = max(dot(norm, light_dir), 0.f);
|
||||||
vec3 diffuse = (diff * u_material.diffuse_strength) * u_light_color;
|
vec3 diffuse = (diff * u_material.diffuse_strength) * u_light_color;
|
||||||
|
|
|
@ -4,6 +4,9 @@ layout (location = 0) in vec3 vertex_position;
|
||||||
layout (location = 1) in vec3 vertex_color;
|
layout (location = 1) in vec3 vertex_color;
|
||||||
layout (location = 2) in vec3 vertex_normal;
|
layout (location = 2) in vec3 vertex_normal;
|
||||||
layout (location = 3) in vec2 vertex_texcoord;
|
layout (location = 3) in vec2 vertex_texcoord;
|
||||||
|
// TODO: Make these optional
|
||||||
|
layout (location = 4) in vec3 vertex_tangent;
|
||||||
|
layout (location = 5) in vec3 vertex_bitangent;
|
||||||
|
|
||||||
out vec3 vs_position;
|
out vec3 vs_position;
|
||||||
out vec3 vs_color;
|
out vec3 vs_color;
|
||||||
|
@ -17,6 +20,11 @@ out vec3 vs_view_pos;
|
||||||
out vec3 vs_light_pos;
|
out vec3 vs_light_pos;
|
||||||
out vec3 vs_frag_pos;
|
out vec3 vs_frag_pos;
|
||||||
|
|
||||||
|
out mat3 vs_tbn;
|
||||||
|
|
||||||
|
out vec3 vs_tangent;
|
||||||
|
out vec3 vs_bitangent;
|
||||||
|
|
||||||
uniform mat4 u_transform_matrix;
|
uniform mat4 u_transform_matrix;
|
||||||
uniform mat4 u_view_matrix;
|
uniform mat4 u_view_matrix;
|
||||||
uniform mat4 u_projection_matrix;
|
uniform mat4 u_projection_matrix;
|
||||||
|
@ -41,4 +49,13 @@ void main() {
|
||||||
vs_light_pos = u_light_position;
|
vs_light_pos = u_light_position;
|
||||||
vs_frag_pos = vec3(u_transform_matrix * vec4(vertex_position, 1.f));
|
vs_frag_pos = vec3(u_transform_matrix * vec4(vertex_position, 1.f));
|
||||||
vs_world_normal = mat3(transpose(inverse(u_transform_matrix))) * vertex_normal; // TODO: Do this calculation on the CPU then send to GPU via a uniform
|
vs_world_normal = mat3(transpose(inverse(u_transform_matrix))) * vertex_normal; // TODO: Do this calculation on the CPU then send to GPU via a uniform
|
||||||
|
|
||||||
|
// Calculate the TBN (Tangent, Bi-tangent, and normal matrix)
|
||||||
|
vec3 T = normalize(vec3(u_transform_matrix * vec4(vertex_tangent, 1.f)));
|
||||||
|
vec3 B = normalize(vec3(u_transform_matrix * vec4(vertex_bitangent, 1.f)));
|
||||||
|
vec3 N = normalize(vec3(u_transform_matrix * vec4(vertex_normal, 1.f)));
|
||||||
|
vs_tbn = mat3(T, B, N);
|
||||||
|
|
||||||
|
vs_tangent = vertex_tangent;
|
||||||
|
vs_bitangent = vertex_bitangent;
|
||||||
}
|
}
|
|
@ -1,23 +1,26 @@
|
||||||
#include "gfx/mesh.h"
|
#include "gfx/mesh.h"
|
||||||
|
#include "gfx/vbo.h"
|
||||||
|
#include "vector.h"
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
namespace simpleengine::gfx {
|
namespace simpleengine::gfx {
|
||||||
Mesh::Mesh(std::vector<LitVertex> vertices, std::vector<GLuint> indicies, Material material) :
|
Mesh::Mesh(std::vector<LitVertex> vertices, std::vector<GLuint> indicies, Material material) :
|
||||||
material(std::make_optional(material)), vertices(vertices), indicies(indicies),
|
material(std::make_optional(material)), vertices(vertices), indicies(indicies),
|
||||||
vbo(gfx::VBO::init(GL_ARRAY_BUFFER, false)), ebo(gfx::VBO::init(GL_ELEMENT_ARRAY_BUFFER, false)),
|
vbo(gfx::VBO::init(GL_ARRAY_BUFFER, false)), ebo(gfx::VBO::init(GL_ELEMENT_ARRAY_BUFFER, false)),
|
||||||
vao(gfx::VAO::init()) {
|
vao(gfx::VAO::init()), tangent_vbo(gfx::VBO::init(GL_ARRAY_BUFFER, false)), bitangent_vbo(gfx::VBO::init(GL_ARRAY_BUFFER, false)) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Mesh::Mesh(std::vector<LitVertex> vertices, std::vector<GLuint> indicies, std::optional<Material> material) :
|
Mesh::Mesh(std::vector<LitVertex> vertices, std::vector<GLuint> indicies, std::optional<Material> material) :
|
||||||
material(material), vertices(vertices), indicies(indicies),
|
material(material), vertices(vertices), indicies(indicies),
|
||||||
vbo(gfx::VBO::init(GL_ARRAY_BUFFER, false)), ebo(gfx::VBO::init(GL_ELEMENT_ARRAY_BUFFER, false)),
|
vbo(gfx::VBO::init(GL_ARRAY_BUFFER, false)), ebo(gfx::VBO::init(GL_ELEMENT_ARRAY_BUFFER, false)),
|
||||||
vao(gfx::VAO::init()) {
|
vao(gfx::VAO::init()), tangent_vbo(gfx::VBO::init(GL_ARRAY_BUFFER, false)), bitangent_vbo(gfx::VBO::init(GL_ARRAY_BUFFER, false)) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Mesh::Mesh(std::vector<LitVertex> vertices, std::vector<GLuint> indicies, Material material, gfx::VBO ebo, gfx::VBO vbo, gfx::VAO vao) :
|
Mesh::Mesh(std::vector<LitVertex> vertices, std::vector<GLuint> indicies, Material material, gfx::VBO ebo, gfx::VBO vbo, gfx::VAO vao,
|
||||||
vertices(vertices), indicies(indicies), material(material), ebo(ebo), vbo(vbo), vao(vao) {
|
gfx::VBO tangent_vbo, gfx::VBO bitangent_vbo) :
|
||||||
|
vertices(vertices), indicies(indicies), material(material), ebo(ebo), vbo(vbo), vao(vao), tangent_vbo(tangent_vbo), bitangent_vbo(bitangent_vbo) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,4 +79,52 @@ namespace simpleengine::gfx {
|
||||||
vertices[i].normal = normals[i];
|
vertices[i].normal = normals[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Mesh::calculate_tangents() {
|
||||||
|
// Resize the tangent and bitangents
|
||||||
|
//tangents.clear();
|
||||||
|
tangents.resize(vertices.size());
|
||||||
|
//bitangents.clear();
|
||||||
|
bitangents.resize(vertices.size());
|
||||||
|
/* std::vector<simpleengine::Vectorf> tangents;
|
||||||
|
std::vector<simpleengine::Vectorf> bitangents; */
|
||||||
|
|
||||||
|
for (int i = 0; i < indicies.size(); i += 3) {
|
||||||
|
int index0 = indicies[i];
|
||||||
|
int index1 = indicies[i+1];
|
||||||
|
int index2 = indicies[i+2];
|
||||||
|
|
||||||
|
LitVertex& lit_vertex0 = vertices[index0];
|
||||||
|
LitVertex& lit_vertex1 = vertices[index1];
|
||||||
|
LitVertex& lit_vertex2 = vertices[index2];
|
||||||
|
|
||||||
|
glm::vec3 pos0 = lit_vertex0.position;
|
||||||
|
glm::vec3 pos1 = lit_vertex1.position;
|
||||||
|
glm::vec3 pos2 = lit_vertex2.position;
|
||||||
|
|
||||||
|
// Edges of the triangle : postion delta
|
||||||
|
glm::vec3 delta_pos1 = pos1 - pos0;
|
||||||
|
glm::vec3 delta_pos2 = pos2 - pos0;
|
||||||
|
|
||||||
|
// UV delta
|
||||||
|
glm::vec2 delta_uv1 = lit_vertex1.tex_coord - lit_vertex0.tex_coord;
|
||||||
|
glm::vec2 delta_uv2 = lit_vertex2.tex_coord - lit_vertex0.tex_coord;
|
||||||
|
|
||||||
|
float r = 1.0f / (delta_uv1.x * delta_uv2.y - delta_uv1.y * delta_uv2.x);
|
||||||
|
glm::vec3 tangent = (delta_pos1 * delta_uv2.y - delta_pos2 * delta_uv1.y)*r;
|
||||||
|
glm::vec3 bitangent = (delta_pos2 * delta_uv1.x - delta_pos1 * delta_uv2.x)*r;
|
||||||
|
|
||||||
|
tangents[index0] = tangent;
|
||||||
|
tangents[index1] = tangent;
|
||||||
|
tangents[index2] = tangent;
|
||||||
|
|
||||||
|
bitangents[index0] = bitangent;
|
||||||
|
bitangents[index1] = bitangent;
|
||||||
|
bitangents[index2] = bitangent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* this->tangents = std::optional<std::pair<std::vector<simpleengine::Vectorf>, std::vector<simpleengine::Vectorf>>>(
|
||||||
|
{tangents, bitangents}
|
||||||
|
); */
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <stdexcept>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -27,13 +28,18 @@ namespace simpleengine::gfx {
|
||||||
if (model_processing_flags & ModelProcessingFlags::MdlProcFlag_FLIP_TEX_COORDS_HORIZONTALLY) {
|
if (model_processing_flags & ModelProcessingFlags::MdlProcFlag_FLIP_TEX_COORDS_HORIZONTALLY) {
|
||||||
horizontally_flip_tex_coords();
|
horizontally_flip_tex_coords();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (model_processing_flags & ModelProcessingFlags::MdlProcFlag_CALCULATE_TANGENT_SPACE) {
|
||||||
|
calculate_tangents();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::load_model(std::string path) {
|
void Model::load_model(std::string path) {
|
||||||
Assimp::Importer importer;
|
Assimp::Importer importer;
|
||||||
|
|
||||||
// assimp post processing options: http://assimp.sourceforge.net/lib_html/postprocess_8h.html
|
// assimp post processing options: http://assimp.sourceforge.net/lib_html/postprocess_8h.html
|
||||||
const aiScene *scene = importer.ReadFile(path, additional_assimp_flags | aiProcess_Triangulate | aiProcess_FlipUVs);
|
const aiScene *scene = importer.ReadFile(path, additional_assimp_flags | aiProcess_Triangulate | aiProcess_FlipUVs
|
||||||
|
| aiProcess_CalcTangentSpace);
|
||||||
|
|
||||||
if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) {
|
if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) {
|
||||||
std::cout << "ERROR::ASSIMP::" << importer.GetErrorString() << std::endl;
|
std::cout << "ERROR::ASSIMP::" << importer.GetErrorString() << std::endl;
|
||||||
|
@ -63,7 +69,7 @@ namespace simpleengine::gfx {
|
||||||
|
|
||||||
gfx::Mesh Model::process_mesh(std::unordered_map<aiTextureType, std::vector<std::shared_ptr<Texture>>>& processed_textures, aiMesh* mesh, const aiScene* scene) {
|
gfx::Mesh Model::process_mesh(std::unordered_map<aiTextureType, std::vector<std::shared_ptr<Texture>>>& processed_textures, aiMesh* mesh, const aiScene* scene) {
|
||||||
std::vector<LitVertex> vertices;
|
std::vector<LitVertex> vertices;
|
||||||
std::vector<unsigned int> indices;
|
std::vector<unsigned int> indicies;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < mesh->mNumVertices; i++) {
|
for (unsigned int i = 0; i < mesh->mNumVertices; i++) {
|
||||||
LitVertex vertex;
|
LitVertex vertex;
|
||||||
|
@ -93,7 +99,7 @@ namespace simpleengine::gfx {
|
||||||
aiFace face = mesh->mFaces[i];
|
aiFace face = mesh->mFaces[i];
|
||||||
|
|
||||||
for (int j = 0; j < face.mNumIndices; j++) {
|
for (int j = 0; j < face.mNumIndices; j++) {
|
||||||
indices.push_back(face.mIndices[j]);
|
indicies.push_back(face.mIndices[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,8 +127,13 @@ namespace simpleengine::gfx {
|
||||||
|
|
||||||
// Load normals texture maps
|
// Load normals texture maps
|
||||||
loading_type = aiTextureType_NORMALS;
|
loading_type = aiTextureType_NORMALS;
|
||||||
std::vector<std::shared_ptr<Texture>> normal_maps = load_material_texture(processed_textures, material, loading_type, TextureFlags::TexFlags_NO_COLOR);
|
std::vector<std::shared_ptr<Texture>> normal_maps = load_material_texture(processed_textures, material, loading_type, TextureFlags::TexFlags_RGB);
|
||||||
if (!normal_maps.empty()) textures.emplace(loading_type, normal_maps);
|
if (!normal_maps.empty()) {
|
||||||
|
textures.emplace(loading_type, normal_maps);
|
||||||
|
|
||||||
|
// Force calculation of tangent space.
|
||||||
|
model_processing_flags |= MdlProcFlag_CALCULATE_TANGENT_SPACE;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO Handle other types of texture maps
|
// TODO Handle other types of texture maps
|
||||||
|
|
||||||
|
@ -156,7 +167,7 @@ namespace simpleengine::gfx {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Mesh se_mesh(vertices, indices, mat);
|
Mesh se_mesh(vertices, indicies, mat);
|
||||||
|
|
||||||
if (!mesh->HasNormals()) {
|
if (!mesh->HasNormals()) {
|
||||||
se_mesh.calculate_normals();
|
se_mesh.calculate_normals();
|
||||||
|
@ -222,4 +233,50 @@ namespace simpleengine::gfx {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Model::calculate_tangents() {
|
||||||
|
for (auto& mesh : meshes) {
|
||||||
|
// TODO: Find a way to check if normals and UVs are set before calculating tangents
|
||||||
|
mesh.calculate_tangents();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* std::vector<std::pair<simpleengine::Vectorf, simpleengine::Vectorf>> calculate_tangent_space(
|
||||||
|
std::vector<LitVertex> vertices, std::vector<unsigned int> indices) {
|
||||||
|
|
||||||
|
std::vector<std::pair<simpleengine::Vectorf, simpleengine::Vectorf>> tangents;
|
||||||
|
tangents.resize(vertices.size());
|
||||||
|
|
||||||
|
for (int i = 0; i < indices.size(); i += 3) {
|
||||||
|
int index0 = indices[i];
|
||||||
|
int index1 = indices[i+1];
|
||||||
|
int index2 = indices[i+2];
|
||||||
|
|
||||||
|
LitVertex& lit_vertex0 = vertices[index0];
|
||||||
|
LitVertex& lit_vertex1 = vertices[index1];
|
||||||
|
LitVertex& lit_vertex2 = vertices[index2];
|
||||||
|
|
||||||
|
glm::vec3 pos0 = lit_vertex0.position;
|
||||||
|
glm::vec3 pos1 = lit_vertex1.position;
|
||||||
|
glm::vec3 pos2 = lit_vertex2.position;
|
||||||
|
|
||||||
|
// Edges of the triangle : postion delta
|
||||||
|
glm::vec3 delta_pos1 = pos1 - pos0;
|
||||||
|
glm::vec3 delta_pos2 = pos2 - pos0;
|
||||||
|
|
||||||
|
// UV delta
|
||||||
|
glm::vec2 delta_uv1 = lit_vertex1.tex_coord - lit_vertex0.tex_coord;
|
||||||
|
glm::vec2 delta_uv2 = lit_vertex2.tex_coord - lit_vertex0.tex_coord;
|
||||||
|
|
||||||
|
float r = 1.0f / (delta_uv1.x * delta_uv2.y - delta_uv1.y * delta_uv2.x);
|
||||||
|
glm::vec3 tangent = (delta_pos1 * delta_uv2.y - delta_pos2 * delta_uv1.y)*r;
|
||||||
|
glm::vec3 bitangent = (delta_pos2 * delta_uv1.x - delta_pos1 * delta_uv2.x)*r;
|
||||||
|
|
||||||
|
tangents[0] = {tangent, bitangent};
|
||||||
|
tangents[1] = {tangent, bitangent};
|
||||||
|
tangents[2] = {tangent, bitangent};
|
||||||
|
}
|
||||||
|
|
||||||
|
return tangents;
|
||||||
|
} */
|
||||||
} // namespace simpleengine::gfx
|
} // namespace simpleengine::gfx
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#include "ecs/component/mesh_component.h"
|
#include "ecs/component/mesh_component.h"
|
||||||
#include "ecs/component/model_component.h"
|
#include "ecs/component/model_component.h"
|
||||||
|
#include "vector.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <assimp/material.h>
|
#include <assimp/material.h>
|
||||||
|
@ -60,8 +61,14 @@ namespace simpleengine::gfx {
|
||||||
vao.enable_attrib(vbo, 2, 3, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, normal), false);
|
vao.enable_attrib(vbo, 2, 3, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, normal), false);
|
||||||
vao.enable_attrib(vbo, 3, 2, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, tex_coord), false);
|
vao.enable_attrib(vbo, 3, 2, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, tex_coord), false);
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
rendering_mesh.tangent_vbo.buffer(rendering_mesh.tangents.data(), 0, rendering_mesh.tangents.size() * sizeof(Vectorf));
|
||||||
glBindVertexArray(0);
|
vao.enable_attrib(rendering_mesh.tangent_vbo, 4, 3, GL_FLOAT, sizeof(Vectorf), 0, false);
|
||||||
|
|
||||||
|
rendering_mesh.bitangent_vbo.buffer(rendering_mesh.bitangents.data(), 0, rendering_mesh.bitangents.size() * sizeof(Vectorf));
|
||||||
|
vao.enable_attrib(rendering_mesh.bitangent_vbo, 5, 3, GL_FLOAT, sizeof(Vectorf), 0, false);
|
||||||
|
|
||||||
|
vbo.unbind();
|
||||||
|
vao.unbind();
|
||||||
|
|
||||||
rendering_mesh.are_buffers_created = true;
|
rendering_mesh.are_buffers_created = true;
|
||||||
|
|
||||||
|
@ -125,6 +132,21 @@ namespace simpleengine::gfx {
|
||||||
} else {
|
} else {
|
||||||
shader.set_uniform_int("u_material.has_specular_map", 0, false);
|
shader.set_uniform_int("u_material.has_specular_map", 0, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Apply the normal map if it exists
|
||||||
|
auto normal_maps = material->textures.find(aiTextureType_NORMALS);
|
||||||
|
if (normal_maps != material->textures.end()) {
|
||||||
|
auto normal = normal_maps->second.front();
|
||||||
|
|
||||||
|
//shader.set_uniform_int("u_material.has_normal_map", 1, false);
|
||||||
|
shader.set_uniform_int("u_material.normal_map", 2, false);
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE2);
|
||||||
|
normal->bind();
|
||||||
|
} else {
|
||||||
|
//shader.set_uniform_int("u_material.has_normal_map", 0, false);
|
||||||
|
std::cout << "No normal map for model!" << std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mesh.vao.bind();
|
mesh.vao.bind();
|
||||||
|
|
Loading…
Reference in New Issue