UnnamedCarGame/src/model/mesh.rs

159 lines
4.8 KiB
Rust

#![allow(non_snake_case)]
#![allow(dead_code)]
use field_offset::offset_of;
use cgmath::{Vector3, Vector2};
use cgmath::prelude::*;
#[repr(C)]
pub struct Vertex {
pub Position: Vector3<f32>,
pub Normal: Vector3<f32>,
pub TexCoords: Vector2<f32>,
pub Tangent: Vector3<f32>,
pub Bitangent: Vector3<f32>,
}
impl Default for Vertex {
fn default () -> Self {
Vertex {
Position: Vector3::zero(),
Normal: Vector3::zero(),
TexCoords: Vector2::zero(),
Tangent: Vector3::zero(),
Bitangent: Vector3::zero(),
}
}
}
#[derive(Clone)]
pub struct Texture {
pub id: u32,
pub type_: String,
pub path: String,
}
#[derive(Default)]
pub struct Mesh {
pub vertices: Vec<Vertex>,
pub indices: Vec<u32>,
pub textures: Vec<Texture>,
pub VAO: u32,
VBO: u32,
EBO: u32,
}
impl Mesh{
pub fn new(vertices: Vec<Vertex>, indices: Vec<u32>, textures: Vec<Texture>) -> Mesh
{
let mut temp = Mesh {
vertices,
indices,
textures,
VAO: 0,
VBO: 0,
EBO: 0,
};
temp.setupMesh();
temp
}
fn setupMesh(&mut self)
{
// create buffers/arrays
unsafe {
gl::GenVertexArrays(1, &mut self.VAO);
gl::GenBuffers(1, &mut self.VBO);
gl::GenBuffers(1, &mut self.EBO);
gl::BindVertexArray(self.VAO);
let size = (self.vertices.len() * std::mem::size_of::<Vertex>()) as isize;
// NOTE, i am not sure if this one will work
gl::BindBuffer(gl::ARRAY_BUFFER, self.VBO);
gl::BufferData(gl::ARRAY_BUFFER, size, self.vertices.as_ptr().cast(), gl::STATIC_DRAW);
// the vertex attribPointers
// vert pox
gl::EnableVertexAttribArray(0);
gl::VertexAttribPointer(0, 3, gl::FLOAT, gl::FALSE, std::mem::size_of::<Vertex>() as i32, 0 as *const _);
// vertex normals
gl::EnableVertexAttribArray(1);
gl::VertexAttribPointer(1, 3, gl::FLOAT, gl::FALSE, std::mem::size_of::<Vertex>() as i32, offset_of!(Vertex => Normal).get_byte_offset() as *const std::os::raw::c_void);
// vertex texture coords
gl::EnableVertexAttribArray(2);
gl::VertexAttribPointer(2, 2, gl::FLOAT, gl::FALSE, std::mem::size_of::<Vertex>() as i32, offset_of!(Vertex => TexCoords).get_byte_offset() as *const std::os::raw::c_void);
//vertex tangent
gl::EnableVertexAttribArray(3);
gl::VertexAttribPointer(3, 3, gl::FLOAT, gl::FALSE, std::mem::size_of::<Vertex>() as i32, offset_of!(Vertex => Tangent).get_byte_offset() as *const std::os::raw::c_void);
// vertex Bitangent
gl::EnableVertexAttribArray(4);
gl::VertexAttribPointer(4, 3, gl::FLOAT, gl::FALSE, std::mem::size_of::<Vertex>() as i32, offset_of!(Vertex => Bitangent).get_byte_offset() as *const std::os::raw::c_void);
gl::BindVertexArray(0);
}
}
// TODO this
pub fn Draw(&self, shader: &crate::shader::shader)
{
let mut diffuseNr = 0;
let mut specularNr = 0;
let mut normalNr = 0;
let mut heightNr = 0;
for (i, texture) in self.textures.iter().enumerate() {
unsafe {gl::ActiveTexture(gl::TEXTURE0 + i as u32)};
let name = &texture.type_;
let number = match name.as_str() {
"texture_diffuse" => {
diffuseNr +=1;
diffuseNr
},
"texture_specular" => {
specularNr += 1;
specularNr
},
"texture_normal" => {
normalNr += 1;
normalNr
},
"texture_height" => {
heightNr += 1;
heightNr
}
_ => panic!("unknown texture type")
};
// set the sampler to the correct texture unit
let sampler = format!("{}{}", name, number);
unsafe{
shader.setInt( &(sampler as String), i as u32 );
gl::BindTexture(gl::TEXTURE_2D, texture.id);
}
}
}
}