Normal/Height maps now working from models, and are only applied to models that have them.

This commit is contained in:
Zed A. Shaw 2026-09-30 17:36:48 -04:00
parent 4efe72b8d8
commit 8b41591360
8 changed files with 170 additions and 12 deletions

View file

@ -112,7 +112,7 @@ void process_input(GLFWwindow *window, std::shared_ptr<Scene> scene) {
std::shared_ptr<Scene> setup() {
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glDisable(GL_CULL_FACE);
glEnable(GL_CULL_FACE);
glEnable(GL_MULTISAMPLE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

View file

@ -14,17 +14,25 @@ void Mesh::draw(Shader &shader, bool with_textures) {
void Mesh::apply_textures(const Shader& shader) {
int texture_i = 1;
bool has_height = false;
for(auto& texture : textures) {
texture.uniform_id = glGetUniformLocation(shader.ID, texture.target.c_str());
if(texture.uniform_id == -1) continue;
if(texture.target.starts_with("texture_height")) {
has_height = true;
}
glActiveTexture(GL_TEXTURE0 + texture_i);
glBindTexture(GL_TEXTURE_2D, texture.id);
glUniform1i(texture.uniform_id, texture_i);
texture_i++;
}
// quick hack to avoid applying height/normal to things without one
shader.setBool("hasHeight", has_height);
}
void Mesh::setup_mesh() {
@ -48,4 +56,10 @@ void Mesh::setup_mesh() {
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, tex_coords));
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, tangent));
glEnableVertexAttribArray(4);
glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, bitangent));
}

View file

@ -13,6 +13,8 @@ struct Vertex {
glm::vec3 position;
glm::vec3 normal;
glm::vec2 tex_coords;
glm::vec3 tangent;
glm::vec3 bitangent;
};
struct TextureCounts {

View file

@ -92,6 +92,8 @@ void Model::draw(Shader &shader, bool with_textures) {
void Model::load_model() {
std::string path = directory + "/" + model_path;
fmt::println("Loading model {}", path);
Assimp::Importer importer;
const aiScene* scene = importer.ReadFile(path,
@ -131,6 +133,8 @@ Mesh Model::process_mesh(const aiScene *scene, aiMesh *mesh) {
glm::vec3 normal{};
glm::vec2 tex_coords{0.0f, 0.0f};
glm::vec3 tangent;
glm::vec3 bitangent;
if(mesh->HasNormals()) {
normal = glm::vec3(
@ -146,7 +150,22 @@ Mesh Model::process_mesh(const aiScene *scene, aiMesh *mesh) {
);
}
vertices.emplace_back(position, normal, tex_coords);
// if has height/normal map
if(mesh->HasTangentsAndBitangents()) {
tangent = glm::vec3(
mesh->mTangents[i].x,
mesh->mTangents[i].y,
mesh->mTangents[i].z
);
bitangent = glm::vec3(
mesh->mBitangents[i].x,
mesh->mBitangents[i].y,
mesh->mBitangents[i].z
);
}
vertices.emplace_back(position, normal, tex_coords, tangent, bitangent);
}
for(unsigned int i = 0; i < mesh->mNumFaces; i++) {
@ -172,17 +191,19 @@ Mesh Model::process_mesh(const aiScene *scene, aiMesh *mesh) {
// 2. specular maps
load_material_textures(scene, textures, material, aiTextureType_SPECULAR, "texture_specular");
// 3. normal maps
load_material_textures(scene, textures, material, aiTextureType_HEIGHT, "texture_normal");
// 3. normal maps, possibly wrong?
load_material_textures(scene, textures, material, aiTextureType_NORMALS, "texture_normal");
// 4. height maps
load_material_textures(scene, textures, material, aiTextureType_AMBIENT, "texture_height");
load_material_textures(scene, textures, material, aiTextureType_HEIGHT, "texture_height");
return Mesh(vertices, indices, textures);
}
void Model::load_material_textures(const aiScene *scene, std::vector<Texture>& textures, aiMaterial *mat, aiTextureType type, std::string type_name)
{
fmt::println(">>> loading texture type {}", type_name);
for(unsigned int i = 0; i < mat->GetTextureCount(type); i++) {
aiString str;
@ -190,6 +211,8 @@ void Model::load_material_textures(const aiScene *scene, std::vector<Texture>& t
std::string tx_path{str.C_Str()};
dbc::check(!tx_path.empty(), "Texture has empty path, should be impossible?");
fmt::println("texture {}", tx_path);
if(textures_loaded.contains(tx_path)) {
textures.push_back(textures_loaded.at(tx_path));
} else {
@ -210,4 +233,6 @@ void Model::load_material_textures(const aiScene *scene, std::vector<Texture>& t
textures_loaded.try_emplace(tx_path, result);
}
}
fmt::println("<<< loading texture type {}", type_name);
}

View file

@ -15,13 +15,13 @@
#include <fstream>
#include <sstream>
#include <iostream>
#include <map>
#include <unordered_map>
#include <vector>
struct Model {
std::string directory;
std::string model_path;
std::map<std::string, Texture> textures_loaded;
std::unordered_map<std::string, Texture> textures_loaded;
std::vector<Mesh> meshes;
TextureCounts texture_counts;
bool gammaCorrection;