mirror of
https://github.com/IllusionMan1212/3dobs.git
synced 2026-10-24 10:12:35 +00:00
feat: basic texture support
- add texture support (ambient, diffuse, specular) - use opacity in fragment shader - calculate normal matrix on cpu for matricies with big determinants
This commit is contained in:
+45
-51
@@ -6,43 +6,15 @@ in vec2 texCoords;
|
||||
out vec4 FragColor;
|
||||
|
||||
struct Material {
|
||||
sampler2D texture_diffuse1;
|
||||
sampler2D texture_diffuse2;
|
||||
sampler2D texture_diffuse3;
|
||||
sampler2D texture_diffuse4;
|
||||
sampler2D texture_diffuse5;
|
||||
sampler2D texture_diffuse6;
|
||||
sampler2D texture_diffuse7;
|
||||
sampler2D texture_diffuse8;
|
||||
sampler2D texture_diffuse9;
|
||||
sampler2D texture_diffuse10;
|
||||
sampler2D texture_diffuse11;
|
||||
sampler2D texture_diffuse12;
|
||||
sampler2D texture_diffuse13;
|
||||
sampler2D texture_diffuse14;
|
||||
sampler2D texture_diffuse15;
|
||||
sampler2D texture_diffuse16;
|
||||
sampler2D texture_specular1;
|
||||
sampler2D texture_specular2;
|
||||
sampler2D texture_specular3;
|
||||
sampler2D texture_specular4;
|
||||
sampler2D texture_specular5;
|
||||
sampler2D texture_specular6;
|
||||
sampler2D texture_specular7;
|
||||
sampler2D texture_specular8;
|
||||
sampler2D texture_specular9;
|
||||
sampler2D texture_specular10;
|
||||
sampler2D texture_specular11;
|
||||
sampler2D texture_specular12;
|
||||
sampler2D texture_specular13;
|
||||
sampler2D texture_specular14;
|
||||
sampler2D texture_specular15;
|
||||
sampler2D texture_specular16;
|
||||
sampler2D texture_diffuse;
|
||||
sampler2D texture_specular;
|
||||
sampler2D texture_ambient;
|
||||
|
||||
vec3 ambient;
|
||||
vec3 diffuse;
|
||||
vec3 specular;
|
||||
float shininess;
|
||||
float opacity;
|
||||
};
|
||||
|
||||
struct DirLight {
|
||||
@@ -88,6 +60,7 @@ uniform Material material;
|
||||
uniform DirLight dirLight;
|
||||
uniform PointLight pointLights[NR_POINT_LIGHTS];
|
||||
uniform SpotLight spotLight;
|
||||
uniform bool useTextures;
|
||||
|
||||
vec3 CalculateDirLight(DirLight light, vec3 normal, vec3 viewDir) {
|
||||
vec3 lightDir = normalize(-light.direction);
|
||||
@@ -103,12 +76,19 @@ vec3 CalculateDirLight(DirLight light, vec3 normal, vec3 viewDir) {
|
||||
spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
|
||||
}
|
||||
|
||||
//vec3 ambient = light.ambient * vec3(texture(material.texture_diffuse1, texCoords)) * material.ambient;
|
||||
//vec3 diffuse = light.diffuse * diff * vec3(texture(material.texture_diffuse1, texCoords)) * material.diffuse;
|
||||
//vec3 specular = light.specular * spec * vec3(texture(material.texture_specular1, texCoords)) * material.specular;
|
||||
vec3 ambient = light.ambient * material.ambient;
|
||||
vec3 diffuse = light.diffuse * (diff * material.diffuse);
|
||||
vec3 specular = light.specular * (spec * material.specular);
|
||||
vec3 ambient = vec3(0.0, 0.0, 0.0);
|
||||
vec3 diffuse = vec3(0.0, 0.0, 0.0);
|
||||
vec3 specular = vec3(0.0, 0.0, 0.0);
|
||||
|
||||
if (useTextures) {
|
||||
ambient = light.ambient * vec3(texture(material.texture_ambient, texCoords)) * material.ambient;
|
||||
diffuse = light.diffuse * diff * vec3(texture(material.texture_diffuse, texCoords)) * material.diffuse;
|
||||
specular = light.specular * spec * vec3(texture(material.texture_specular, texCoords)) * material.specular;
|
||||
} else {
|
||||
ambient = light.ambient * material.ambient;
|
||||
diffuse = light.diffuse * (diff * material.diffuse);
|
||||
specular = light.specular * (spec * material.specular);
|
||||
}
|
||||
|
||||
return (ambient + diffuse + specular);
|
||||
}
|
||||
@@ -131,12 +111,19 @@ vec3 CalculatePointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewD
|
||||
float distance = length(light.position - fragPos);
|
||||
float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance + distance));
|
||||
|
||||
//vec3 ambient = light.ambient * vec3(texture(material.texture_diffuse1, texCoords)) * material.ambient;
|
||||
//vec3 diffuse = light.diffuse * diff * vec3(texture(material.texture_diffuse1, texCoords)) * material.diffuse;
|
||||
//vec3 specular = light.specular * spec * vec3(texture(material.texture_specular1, texCoords)) * material.specular;
|
||||
vec3 ambient = light.ambient * material.ambient;
|
||||
vec3 diffuse = light.diffuse * (diff * material.diffuse);
|
||||
vec3 specular = light.specular * (spec * material.specular);
|
||||
vec3 ambient = vec3(0.0, 0.0, 0.0);
|
||||
vec3 diffuse = vec3(0.0, 0.0, 0.0);
|
||||
vec3 specular = vec3(0.0, 0.0, 0.0);
|
||||
|
||||
if (useTextures) {
|
||||
ambient = light.ambient * vec3(texture(material.texture_ambient, texCoords)) * material.ambient;
|
||||
diffuse = light.diffuse * diff * vec3(texture(material.texture_diffuse, texCoords)) * material.diffuse;
|
||||
specular = light.specular * spec * vec3(texture(material.texture_specular, texCoords)) * material.specular;
|
||||
} else {
|
||||
ambient = light.ambient * material.ambient;
|
||||
diffuse = light.diffuse * (diff * material.diffuse);
|
||||
specular = light.specular * (spec * material.specular);
|
||||
}
|
||||
|
||||
ambient *= attenuation;
|
||||
diffuse *= attenuation;
|
||||
@@ -168,12 +155,19 @@ vec3 CalculateSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir
|
||||
float epsilon = light.cutOff - light.outerCutOff;
|
||||
float intensity = clamp((theta - light.outerCutOff) / epsilon, 0.0, 1.0);
|
||||
|
||||
//vec3 ambient = light.ambient * vec3(texture(material.texture_diffuse1, texCoords)) * material.ambient;
|
||||
//vec3 diffuse = light.diffuse * diff * vec3(texture(material.texture_diffuse1, texCoords)) * material.diffuse;
|
||||
//vec3 specular = light.specular * spec * vec3(texture(material.texture_specular1, texCoords)) * material.specular;
|
||||
vec3 ambient = light.ambient * material.ambient;
|
||||
vec3 diffuse = light.diffuse * (diff * material.diffuse);
|
||||
vec3 specular = light.specular * (spec * material.specular);
|
||||
vec3 ambient = vec3(0.0, 0.0, 0.0);
|
||||
vec3 diffuse = vec3(0.0, 0.0, 0.0);
|
||||
vec3 specular = vec3(0.0, 0.0, 0.0);
|
||||
|
||||
if (useTextures) {
|
||||
ambient = light.ambient * vec3(texture(material.texture_ambient, texCoords)) * material.ambient;
|
||||
diffuse = light.diffuse * diff * vec3(texture(material.texture_diffuse, texCoords)) * material.diffuse;
|
||||
specular = light.specular * spec * vec3(texture(material.texture_specular, texCoords)) * material.specular;
|
||||
} else {
|
||||
ambient = light.ambient * material.ambient;
|
||||
diffuse = light.diffuse * (diff * material.diffuse);
|
||||
specular = light.specular * (spec * material.specular);
|
||||
}
|
||||
|
||||
diffuse *= intensity;
|
||||
specular *= intensity;
|
||||
@@ -200,6 +194,6 @@ void main()
|
||||
|
||||
result += CalculateSpotLight(spotLight, norm, fragPos, viewDir);
|
||||
|
||||
FragColor = vec4(result, 1.0);
|
||||
FragColor = vec4(result, material.opacity);
|
||||
}
|
||||
|
||||
|
||||
+5
-1
@@ -10,11 +10,15 @@ uniform mat4 model;
|
||||
uniform mat4 view;
|
||||
uniform mat4 projection;
|
||||
uniform mat3 normalMatrix;
|
||||
uniform bool useNormalMatrix;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = projection * view * model * vec4(aPos, 1.0f);
|
||||
fragNormals = normalMatrix * aNormal;
|
||||
if (useNormalMatrix)
|
||||
fragNormals = normalMatrix * aNormal;
|
||||
else
|
||||
fragNormals = mat3(transpose(inverse(model))) * aNormal;
|
||||
fragPos = vec3(model * vec4(aPos, 1.0));
|
||||
texCoords = aTexCoords;
|
||||
}
|
||||
|
||||
+44
-9
@@ -1,9 +1,9 @@
|
||||
mod obj;
|
||||
mod stl;
|
||||
|
||||
use std::{path::PathBuf, collections::HashMap};
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::{mesh::Vertex, aabb::AABB, utils::SupportedFileExtensions};
|
||||
use crate::{mesh::Vertex, aabb::AABB, utils::{SupportedFileExtensions, self}};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum TextureType {
|
||||
@@ -18,7 +18,23 @@ pub enum TextureType {
|
||||
Emissive
|
||||
}
|
||||
|
||||
// TODO: take the textures out of the material and put it on the model/object
|
||||
impl TextureType {
|
||||
pub fn from_material_str(token: &str) -> Option<Self> {
|
||||
match token {
|
||||
"map_Ka" => Some(TextureType::Ambient),
|
||||
"map_Kd" => Some(TextureType::Diffuse),
|
||||
"map_Ks" => Some(TextureType::Specular),
|
||||
"map_Ns" => Some(TextureType::SpecularHighlight),
|
||||
"map_bump" => Some(TextureType::Bump),
|
||||
"map_d" => Some(TextureType::Displacement),
|
||||
"decal" => Some(TextureType::Decal),
|
||||
"refl" => Some(TextureType::Reflection),
|
||||
"map_Ke" => Some(TextureType::Emissive),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Material {
|
||||
pub name: String,
|
||||
@@ -27,11 +43,11 @@ pub struct Material {
|
||||
pub specular_color: glm::Vec3,
|
||||
pub specular_exponent: f32,
|
||||
pub opacity: f32,
|
||||
pub textures: HashMap<String, TextureType>,
|
||||
pub textures: Vec<Texture>
|
||||
}
|
||||
|
||||
impl Material {
|
||||
fn new(name: String, ambient: glm::Vec3, diffuse: glm::Vec3, specular: glm::Vec3, shininess: f32, opacity: f32, textures: HashMap<String, TextureType>) -> Self {
|
||||
fn new(name: String, ambient: glm::Vec3, diffuse: glm::Vec3, specular: glm::Vec3, shininess: f32, opacity: f32, textures: Vec<Texture>) -> Self {
|
||||
Self {
|
||||
name,
|
||||
ambient_color: ambient,
|
||||
@@ -53,7 +69,7 @@ impl Default for Material {
|
||||
specular_color: glm::vec3(0.1, 0.1, 0.1),
|
||||
specular_exponent: 32.0,
|
||||
opacity: 1.0,
|
||||
textures: HashMap::new()
|
||||
textures: Vec::new()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -62,16 +78,35 @@ impl std::fmt::Display for Material {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"Ambient: {:?}\nDiffuse: {:?}\nSpecular: {:?}\nShininess: {}\nOpacity: {}",
|
||||
"Ambient: {:?}\nDiffuse: {:?}\nSpecular: {:?}\nShininess: {}\nOpacity: {}\nTextures: {:?}",
|
||||
self.ambient_color,
|
||||
self.diffuse_color,
|
||||
self.specular_color,
|
||||
self.specular_exponent,
|
||||
self.opacity
|
||||
self.opacity,
|
||||
self.textures
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Texture {
|
||||
pub id: u32,
|
||||
pub typ: TextureType,
|
||||
}
|
||||
|
||||
impl Texture {
|
||||
pub fn new(path: std::path::PathBuf, typ: TextureType) -> Result<Self, Box<dyn std::error::Error>> {
|
||||
let id = utils::load_texture(path)?;
|
||||
|
||||
Ok(Texture {
|
||||
id,
|
||||
typ,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ObjMesh {
|
||||
pub name: String,
|
||||
@@ -84,7 +119,7 @@ pub struct ObjMesh {
|
||||
pub struct Object {
|
||||
pub name: String,
|
||||
pub meshes: Vec<ObjMesh>,
|
||||
pub aabb: AABB
|
||||
pub aabb: AABB,
|
||||
}
|
||||
|
||||
pub fn load_from_file(path: &PathBuf) -> Result<Object, Box<dyn std::error::Error>> {
|
||||
|
||||
+34
-8
@@ -2,7 +2,7 @@ use std::{io::{BufReader, BufRead}, collections::HashMap, path::PathBuf};
|
||||
|
||||
use log::{error, warn, trace};
|
||||
|
||||
use crate::{mesh::Vertex, aabb::AABB, importer::ObjMesh, importer::Object, importer::Material};
|
||||
use crate::{mesh::Vertex, aabb::AABB, importer::{ObjMesh, Object, Material, Texture, TextureType}};
|
||||
|
||||
const BUF_CAP: usize = 1024 * 128; // 128 Kilobytes
|
||||
|
||||
@@ -84,7 +84,7 @@ impl MtlToken {
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_mtl(path: &PathBuf) -> Result<HashMap<String, Material>, Box<dyn std::error::Error>> {
|
||||
fn parse_mtl(path: &PathBuf, obj_textures: &mut HashMap<String, Texture>) -> Result<HashMap<String, Material>, Box<dyn std::error::Error>> {
|
||||
let file = std::fs::File::open(path)?;
|
||||
let reader = BufReader::with_capacity(BUF_CAP, file);
|
||||
let mut material_name = String::new();
|
||||
@@ -95,6 +95,7 @@ fn parse_mtl(path: &PathBuf) -> Result<HashMap<String, Material>, Box<dyn std::e
|
||||
let mut specular = glm::vec3(0.0, 0.0, 0.0);
|
||||
let mut shininess = 32.0;
|
||||
let mut opacity = 1.0;
|
||||
let mut mat_textures: Vec<Texture> = Vec::new();
|
||||
|
||||
for line in reader.lines() {
|
||||
let line = line?;
|
||||
@@ -109,8 +110,10 @@ fn parse_mtl(path: &PathBuf) -> Result<HashMap<String, Material>, Box<dyn std::e
|
||||
match MtlToken::from_str(token) {
|
||||
Some(MtlToken::NewMaterial) => {
|
||||
if !material_name.is_empty() {
|
||||
material = Material::new(material_name.clone(), ambient, diffuse, specular, shininess, opacity, HashMap::new());
|
||||
material = Material::new(material_name.clone(), ambient, diffuse, specular, shininess, opacity, mat_textures.clone());
|
||||
materials.insert(material_name, material);
|
||||
|
||||
mat_textures.clear();
|
||||
}
|
||||
|
||||
material_name = iter.next().unwrap().to_string();
|
||||
@@ -139,15 +142,36 @@ fn parse_mtl(path: &PathBuf) -> Result<HashMap<String, Material>, Box<dyn std::e
|
||||
Some(MtlToken::Opacity) => {
|
||||
opacity = iter.next().unwrap().parse::<f32>().unwrap();
|
||||
}
|
||||
Some(MtlToken::DiffuseTexture) => {
|
||||
// TODO: textures
|
||||
Some(MtlToken::DiffuseTexture)
|
||||
| Some(MtlToken::AmbientTexture)
|
||||
| Some(MtlToken::SpecularTexture) => {
|
||||
let tex_type = TextureType::from_material_str(token).unwrap();
|
||||
|
||||
let name = iter.next().unwrap().to_string();
|
||||
let mat = if obj_textures.contains_key(&name) {
|
||||
obj_textures.get(&name).unwrap().clone()
|
||||
} else {
|
||||
let path = path.parent().unwrap().join(&name);
|
||||
let tex = match Texture::new(path, tex_type) {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
error!("Failed to load texture: {}", e);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
obj_textures.insert(name, tex.clone());
|
||||
tex
|
||||
};
|
||||
|
||||
mat_textures.push(mat);
|
||||
}
|
||||
_ => { warn!("Unhandled material token: {}", token) },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
material = Material::new(material_name.clone(), ambient, diffuse, specular, shininess, opacity, HashMap::new());
|
||||
material = Material::new(material_name.clone(), ambient, diffuse, specular, shininess, opacity, mat_textures);
|
||||
|
||||
materials.insert(material_name, material);
|
||||
|
||||
@@ -170,6 +194,7 @@ pub fn load_obj(obj_path: &PathBuf, file: std::fs::File) -> Result<Object, Box<d
|
||||
let mut current_material: Option<Material> = None;
|
||||
let mut min_aabb = glm::vec3(f32::MAX, f32::MAX, f32::MAX);
|
||||
let mut max_aabb = glm::vec3(f32::MIN, f32::MIN, f32::MIN);
|
||||
let mut textures = HashMap::new();
|
||||
|
||||
for line in reader.lines() {
|
||||
let line = line?;
|
||||
@@ -264,7 +289,8 @@ pub fn load_obj(obj_path: &PathBuf, file: std::fs::File) -> Result<Object, Box<d
|
||||
.map(|i| i.parse::<f32>().unwrap());
|
||||
let u = iter.next().unwrap();
|
||||
let v = iter.next().unwrap();
|
||||
tex_coords.push(glm::vec2(u, v));
|
||||
// vertically flip the texcoords because flipping the texture is expensive
|
||||
tex_coords.push(glm::vec2(u, 1.0 - v));
|
||||
}
|
||||
Some(ObjToken::Face) => {
|
||||
let face = iter.collect::<Vec<_>>();
|
||||
@@ -372,7 +398,7 @@ pub fn load_obj(obj_path: &PathBuf, file: std::fs::File) -> Result<Object, Box<d
|
||||
Some(ObjToken::MaterialLib) => {
|
||||
for matlib in iter {
|
||||
let material_path = obj_path.parent().unwrap().join(matlib);
|
||||
let new_materials = parse_mtl(&material_path);
|
||||
let new_materials = parse_mtl(&material_path, &mut textures);
|
||||
match new_materials {
|
||||
Ok(m) => {
|
||||
materials.extend(m);
|
||||
|
||||
+1
-1
@@ -264,7 +264,7 @@ fn main() -> anyhow::Result<(), Box<dyn std::error::Error>> {
|
||||
} else {
|
||||
gl::PolygonMode(gl::FRONT_AND_BACK, gl::FILL);
|
||||
}
|
||||
if Some(obj.id) == state.active_model {obj.draw(&mesh_shader, state.draw_aabb);}
|
||||
if Some(obj.id) == state.active_model {obj.draw(&mesh_shader, state.draw_aabb, state.show_textures);}
|
||||
}
|
||||
gl::PolygonMode(gl::FRONT_AND_BACK, gl::FILL);
|
||||
|
||||
|
||||
+46
-56
@@ -1,6 +1,7 @@
|
||||
use glad_gl::gl;
|
||||
use log::warn;
|
||||
|
||||
use crate::{shader::Shader, utils, importer::Material};
|
||||
use crate::{shader::Shader, utils, importer::{Material, TextureType}};
|
||||
|
||||
fn create_rotation_matrix(pitch: f32, yaw: f32, roll: f32, pivot: glm::Vec3) -> glm::Mat4 {
|
||||
let pitch = pitch.to_radians();
|
||||
@@ -36,7 +37,6 @@ pub struct Mesh {
|
||||
|
||||
pub vertices: Vec<Vertex>,
|
||||
pub indices: Vec<u32>,
|
||||
// pub textures: Vec<Texture>,
|
||||
pub material: Material,
|
||||
|
||||
vao: u32,
|
||||
@@ -82,7 +82,6 @@ impl Mesh {
|
||||
name: name.to_string(),
|
||||
vertices,
|
||||
indices,
|
||||
// textures,
|
||||
material: material.unwrap_or_default(),
|
||||
vbo,
|
||||
vao,
|
||||
@@ -94,23 +93,26 @@ impl Mesh {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn draw(&self, shader: &Shader, scale: f32, pivot: glm::Vec3) {
|
||||
// let mut diffuse = 1;
|
||||
// let mut specular = 1;
|
||||
|
||||
pub fn draw(&self, shader: &Shader, scale: f32, pivot: glm::Vec3, show_textures: bool) {
|
||||
shader.use_shader();
|
||||
|
||||
let model_mat = glm::ext::scale(&utils::mat_ident(), glm::vec3(scale, scale, scale));
|
||||
let model_mat = apply_rotation(&model_mat, self.rotation, pivot);
|
||||
let model_mat = glm::ext::translate(&model_mat, glm::vec3(self.position.x, self.position.y, self.position.z));
|
||||
shader.set_mat4fv("model", &model_mat);
|
||||
let normal_mat = glm::transpose(&glm::inverse(&model_mat));
|
||||
let normal_mat = glm::mat3(
|
||||
normal_mat[0][0], normal_mat[0][1], normal_mat[0][2],
|
||||
normal_mat[1][0], normal_mat[1][1], normal_mat[1][2],
|
||||
normal_mat[2][0], normal_mat[2][1], normal_mat[2][2],
|
||||
);
|
||||
shader.set_mat3fv("normalMatrix", &normal_mat);
|
||||
|
||||
if glm::ext::is_invertible(&model_mat) {
|
||||
let normal_mat = glm::transpose(&glm::inverse(&model_mat));
|
||||
let normal_mat = glm::mat3(
|
||||
normal_mat[0][0], normal_mat[0][1], normal_mat[0][2],
|
||||
normal_mat[1][0], normal_mat[1][1], normal_mat[1][2],
|
||||
normal_mat[2][0], normal_mat[2][1], normal_mat[2][2],
|
||||
);
|
||||
shader.set_mat3fv("normalMatrix", &normal_mat);
|
||||
shader.set_bool("useNormalMatrix", true);
|
||||
} else {
|
||||
shader.set_bool("useNormalMatrix", false);
|
||||
}
|
||||
|
||||
let mut polygon_mode = 0;
|
||||
unsafe {
|
||||
@@ -119,34 +121,44 @@ impl Mesh {
|
||||
let is_wireframe = polygon_mode as u32 == gl::LINE;
|
||||
|
||||
if !is_wireframe {
|
||||
// TODO: these can be missing in the (.obj) material, maybe we should set them
|
||||
// to 1.0 as fallback. shininess too
|
||||
shader.set_3fv("material.ambient", self.material.ambient_color);
|
||||
shader.set_3fv("material.diffuse", self.material.diffuse_color);
|
||||
shader.set_3fv("material.specular", self.material.specular_color);
|
||||
shader.set_float("material.shininess", self.material.specular_exponent);
|
||||
shader.set_float("material.shininess", 32.0);
|
||||
shader.set_float("material.opacity", self.material.opacity);
|
||||
} else {
|
||||
shader.set_3fv("material.ambient", glm::vec3(0.0, 0.0, 0.0));
|
||||
shader.set_3fv("material.diffuse", glm::vec3(0.0, 0.0, 0.0));
|
||||
}
|
||||
|
||||
// for i in 0..self.textures.len() {
|
||||
// unsafe {
|
||||
// gl::ActiveTexture(gl::TEXTURE0 + i as u32);
|
||||
// match self.textures[i].typ {
|
||||
// russimp::material::TextureType::Diffuse => {
|
||||
// diffuse += 1;
|
||||
// shader.set_int(format!("material.texture_diffuse{}", diffuse).as_str(), i as i32);
|
||||
// },
|
||||
// russimp::material::TextureType::Specular => {
|
||||
// specular += 1;
|
||||
// shader.set_int(format!("material.texture_specular{}", specular).as_str(), i as i32);
|
||||
// },
|
||||
// _ => {}, // don't do anything because unsupported texture types are logged
|
||||
// // when the model is loaded
|
||||
// }
|
||||
if show_textures {
|
||||
shader.set_bool("useTextures", self.material.textures.len() > 0);
|
||||
for (i, tex) in self.material.textures.iter().enumerate() {
|
||||
unsafe {
|
||||
gl::ActiveTexture(gl::TEXTURE0 + i as u32);
|
||||
match tex.typ {
|
||||
TextureType::Ambient => {
|
||||
shader.set_int("material.texture_ambient", i as i32);
|
||||
},
|
||||
TextureType::Diffuse => {
|
||||
shader.set_int("material.texture_diffuse", i as i32);
|
||||
},
|
||||
TextureType::Specular => {
|
||||
shader.set_int("material.texture_specular{}", i as i32);
|
||||
},
|
||||
_ => {
|
||||
warn!("Unsupported texture type: {:?}", tex.typ);
|
||||
},
|
||||
}
|
||||
|
||||
// gl::BindTexture(gl::TEXTURE_2D, self.textures[i].id);
|
||||
// }
|
||||
// }
|
||||
gl::BindTexture(gl::TEXTURE_2D, tex.id);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
shader.set_bool("useTextures", false);
|
||||
}
|
||||
|
||||
unsafe {
|
||||
// draw Mesh
|
||||
@@ -170,6 +182,7 @@ impl Mesh {
|
||||
|
||||
impl Drop for Mesh {
|
||||
fn drop(&mut self) {
|
||||
// TODO: should we impl a Drop on material to delete the textures from gpu??
|
||||
unsafe {
|
||||
gl::BindVertexArray(0);
|
||||
gl::DeleteBuffers(1, &self.vbo);
|
||||
@@ -197,26 +210,3 @@ impl Vertex {
|
||||
}
|
||||
}
|
||||
|
||||
// #[derive(Clone, Debug)]
|
||||
// pub struct Texture {
|
||||
// pub id: u32,
|
||||
// pub typ: russimp::material::TextureType,
|
||||
// pub path: std::path::PathBuf,
|
||||
// }
|
||||
|
||||
// impl Texture {
|
||||
// pub fn new(path: std::path::PathBuf, typ: russimp::material::TextureType) -> Result<Self, Box<dyn std::error::Error>> {
|
||||
// let path_str = match path.to_str() {
|
||||
// Some(path) => path,
|
||||
// None => return Err("Failed to convert texture path to string".into()),
|
||||
// };
|
||||
// let id = utils::load_texture(path_str)?;
|
||||
|
||||
// Ok(Texture {
|
||||
// id,
|
||||
// typ,
|
||||
// path,
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
+2
-51
@@ -12,55 +12,6 @@ pub struct Model {
|
||||
pub mem_usage: usize,
|
||||
}
|
||||
|
||||
// TODO: texture support, kept for reference
|
||||
// fn load_material_textures(
|
||||
// mat: &russimp::material::Material,
|
||||
// dir: &std::path::PathBuf,
|
||||
// loaded_textures: &mut Vec<Texture>
|
||||
// ) -> (Vec<Texture>, Vec<Box<dyn std::error::Error>>) {
|
||||
|
||||
// let mut textures = vec![];
|
||||
// let mut errors = vec![];
|
||||
|
||||
// for (typ, tex) in mat.textures.iter() {
|
||||
// if SUPPORTED_TEXTURE_TYPES.contains(typ) {
|
||||
// let texture = tex.borrow();
|
||||
// let mut skip = false;
|
||||
// let tex_filename = &texture.filename;
|
||||
// // HACK: fix this
|
||||
// if tex_filename.is_empty() {
|
||||
// continue;
|
||||
// }
|
||||
// // println!("texture filename: {}", tex_filename);
|
||||
// let path = dir.join(tex_filename);
|
||||
|
||||
// for loaded_tex in &mut *loaded_textures {
|
||||
// if loaded_tex.path == path {
|
||||
// textures.push(loaded_tex.clone());
|
||||
// skip = true;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
// if !skip {
|
||||
// match Texture::new(path, *typ) {
|
||||
// Ok(texture) => {
|
||||
// loaded_textures.push(texture.clone());
|
||||
// textures.push(texture);
|
||||
// },
|
||||
// Err(e) => {
|
||||
// let err = anyhow!("Error loading texture: {}", e);
|
||||
// println!("{}", err);
|
||||
// errors.push(err.into());
|
||||
// },
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// return (textures, errors);
|
||||
// }
|
||||
|
||||
impl Model {
|
||||
pub fn new(obj: importer::Object, state: &mut ui::State) -> Model {
|
||||
let mut meshes = Vec::new();
|
||||
@@ -90,7 +41,7 @@ impl Model {
|
||||
return model;
|
||||
}
|
||||
|
||||
pub fn draw(&self, shader: &Shader, draw_aabb: bool) {
|
||||
pub fn draw(&self, shader: &Shader, draw_aabb: bool, show_textures: bool) {
|
||||
let center_x = ((self.aabb.max.x / 2.0) + (self.aabb.min.x / 2.0)) * self.scaling_factor;
|
||||
let center_y = ((self.aabb.max.y / 2.0) + (self.aabb.min.y / 2.0)) * self.scaling_factor;
|
||||
let center_z = ((self.aabb.max.z / 2.0) + (self.aabb.min.z / 2.0)) * self.scaling_factor;
|
||||
@@ -102,7 +53,7 @@ impl Model {
|
||||
|
||||
|
||||
for mesh in &self.meshes {
|
||||
mesh.draw(shader, self.scaling_factor, pivot);
|
||||
mesh.draw(shader, self.scaling_factor, pivot, show_textures);
|
||||
}
|
||||
|
||||
if draw_aabb {
|
||||
|
||||
@@ -31,6 +31,7 @@ pub struct State {
|
||||
pub logger: logger::WritableLog,
|
||||
pub settings: Settings,
|
||||
pub fps: f32,
|
||||
pub show_textures: bool
|
||||
}
|
||||
|
||||
impl Default for State {
|
||||
@@ -55,6 +56,7 @@ impl Default for State {
|
||||
logger: logger::WritableLog::default(),
|
||||
settings: Settings::default(),
|
||||
fps: 0.0,
|
||||
show_textures: true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -487,6 +489,8 @@ fn draw_viewport(ui: &imgui::Ui, state: &mut State, texture: u32) {
|
||||
ui.same_line();
|
||||
ui.checkbox("FOV zoom", &mut state.fov_zoom);
|
||||
ui.same_line();
|
||||
ui.checkbox("Show Textures", &mut state.show_textures);
|
||||
ui.same_line();
|
||||
ui.set_next_item_width(150.0);
|
||||
imgui::Drag::new("Camera Speed")
|
||||
.range(1.0, 10000.0)
|
||||
|
||||
+9
-4
@@ -22,11 +22,11 @@ impl SupportedFileExtensions {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load_texture(path: &str) -> Result<u32> {
|
||||
let tex = image::io::Reader::open(path)
|
||||
.with_context(|| format!("Failed to open texture file: {}", path))?
|
||||
pub fn load_texture(path: PathBuf) -> Result<u32> {
|
||||
let tex = image::io::Reader::open(path.clone())
|
||||
.with_context(|| format!("Failed to open texture file: {:?}", path))?
|
||||
.decode()
|
||||
.with_context(|| format!("Failed to decode texture: {}", path))?;
|
||||
.with_context(|| format!("Failed to decode texture: {:?}", path))?;
|
||||
|
||||
let mut texture_id: u32 = 0;
|
||||
let format = match tex.color().channel_count() {
|
||||
@@ -38,6 +38,9 @@ pub fn load_texture(path: &str) -> Result<u32> {
|
||||
};
|
||||
|
||||
unsafe {
|
||||
// set alignment to 1 since we use u8 for the pixel data type
|
||||
gl::PixelStorei(gl::UNPACK_ALIGNMENT, 1);
|
||||
|
||||
gl::GenTextures(1, &mut texture_id);
|
||||
gl::BindTexture(gl::TEXTURE_2D, texture_id);
|
||||
|
||||
@@ -49,6 +52,8 @@ pub fn load_texture(path: &str) -> Result<u32> {
|
||||
|
||||
gl::TexImage2D(gl::TEXTURE_2D, 0, format as i32, tex.width() as i32, tex.height() as i32, 0, format, gl::UNSIGNED_BYTE, tex.as_bytes().as_ptr() as *const std::ffi::c_void);
|
||||
gl::GenerateMipmap(gl::TEXTURE_2D);
|
||||
|
||||
gl::PixelStorei(gl::UNPACK_ALIGNMENT, 4);
|
||||
}
|
||||
|
||||
Ok(texture_id)
|
||||
|
||||
Reference in New Issue
Block a user