added Model.rs
parent
5fa37d5f06
commit
19a8b30997
|
@ -8,8 +8,9 @@ edition = "2021"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
gl = "0.14.0"
|
gl = "0.14.0"
|
||||||
glm = "0.2.3"
|
glm = "0.2.3"
|
||||||
stb = { version = "0.3.2", default-features = false, features = ["stb_image"] }
|
|
||||||
field-offset = "0.3.4"
|
field-offset = "0.3.4"
|
||||||
|
image = "0.24.5"
|
||||||
|
tobj = "3.2.4"
|
||||||
|
cgmath = "0.18.0"
|
||||||
[dependencies.glfw]
|
[dependencies.glfw]
|
||||||
version = "*"
|
version = "*"
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 1.8 MiB |
|
@ -0,0 +1,16 @@
|
||||||
|
# Blender MTL File: 'None'
|
||||||
|
# Material Count: 1
|
||||||
|
|
||||||
|
newmtl Scene_-_Root
|
||||||
|
Ns 225.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Kd 0.800000 0.800000 0.800000
|
||||||
|
Ks 0.500000 0.500000 0.500000
|
||||||
|
Ke 0.0 0.0 0.0
|
||||||
|
Ni 1.450000
|
||||||
|
d 1.000000
|
||||||
|
illum 2
|
||||||
|
map_Kd diffuse.jpg
|
||||||
|
map_Bump normal.png
|
||||||
|
map_Ks specular.jpg
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
After Width: | Height: | Size: 5.8 MiB |
Binary file not shown.
After Width: | Height: | Size: 14 MiB |
Binary file not shown.
After Width: | Height: | Size: 4.2 MiB |
|
@ -0,0 +1,3 @@
|
||||||
|
Model by Berk Gedik, from: https://sketchfab.com/3d-models/survival-guitar-backpack-low-poly-799f8c4511f84fab8c3f12887f7e6b36
|
||||||
|
|
||||||
|
Modified material assignment (Joey de Vries) for easier load in OpenGL model loading chapter, and renamed albedo to diffuse and metallic to specular to match non-PBR lighting setup.
|
Binary file not shown.
After Width: | Height: | Size: 6.4 MiB |
|
@ -0,0 +1,12 @@
|
||||||
|
|
||||||
|
#version 330 core
|
||||||
|
out vec4 FragColor;
|
||||||
|
|
||||||
|
in vec2 TexCoords;
|
||||||
|
|
||||||
|
uniform sampler2D texture_diffuse1;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
FragColor = texture(texture_diffuse1, TexCoords);
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
|
||||||
|
#version 330 core
|
||||||
|
layout (location = 0) in vec3 aPos;
|
||||||
|
layout (location = 1) in vec3 aNormal;
|
||||||
|
layout (location = 2) in vec2 aTexCoords;
|
||||||
|
|
||||||
|
out vec2 TexCoords;
|
||||||
|
|
||||||
|
uniform mat4 model;
|
||||||
|
uniform mat4 view;
|
||||||
|
uniform mat4 projection;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
TexCoords = aTexCoords;
|
||||||
|
gl_Position = projection * view * model * vec4(aPos, 1.0);
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
#version 330 core
|
||||||
|
out vec4 Color;
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
Color = vec4(0.9, 0.5, 0.2, 1.0);
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
#version 330 core
|
||||||
|
layout (location = 0) in vec3 position;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = vec4(position, 1.0);
|
||||||
|
// gl_Position = vec4(position.xyz, 1.0);
|
||||||
|
// gl_Position = vec4(position.x, position.y, position.z, 1.0);
|
||||||
|
}
|
19
src/main.rs
19
src/main.rs
|
@ -3,14 +3,15 @@ use std::convert::TryInto;
|
||||||
use glfw;
|
use glfw;
|
||||||
use glfw::{Action, Context, Key};
|
use glfw::{Action, Context, Key};
|
||||||
use gl;
|
use gl;
|
||||||
|
use cgmath::{Matrix4, vec3, Point3, Deg, perspective};
|
||||||
|
|
||||||
const ScreenWidth: u32 = 480;
|
const ScreenWidth: u32 = 480;
|
||||||
const ScreenHeight: u32 = 320;
|
const ScreenHeight: u32 = 320;
|
||||||
const TITLE: &str = "GLFWtest";
|
const TITLE: &str = "GLFWtest";
|
||||||
|
|
||||||
mod shader;
|
mod shader;
|
||||||
mod mesh;
|
mod model;
|
||||||
|
use model::Model;
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
||||||
// initialize GLFW
|
// initialize GLFW
|
||||||
|
@ -37,11 +38,13 @@ fn main() {
|
||||||
unsafe {
|
unsafe {
|
||||||
gl::Viewport(0, 0, screen_width, screen_height);
|
gl::Viewport(0, 0, screen_width, screen_height);
|
||||||
gl::ClearColor(1.0, 1.0, 1.0, 1.0);
|
gl::ClearColor(1.0, 1.0, 1.0, 1.0);
|
||||||
|
gl::Enable(gl::DEPTH_TEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// put biggie thingies here
|
// put biggie thingies here
|
||||||
let test_Shader = shader::shader::new("basic");
|
let model_Shader = shader::shader::new("model");
|
||||||
|
let ourModel = Model::new("backpack/backpack.obj");
|
||||||
|
|
||||||
// NOTE window loop
|
// NOTE window loop
|
||||||
while !window.should_close() {
|
while !window.should_close() {
|
||||||
|
@ -50,13 +53,17 @@ fn main() {
|
||||||
glfw_handle_event(&mut window, event);
|
glfw_handle_event(&mut window, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
clear_color(0.1, 0.1, 0.1, -0.0);
|
model_Shader.Use();
|
||||||
|
|
||||||
|
|
||||||
|
// view/projection transformations
|
||||||
|
//let projection:;
|
||||||
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
gl::Clear(gl::COLOR_BUFFER_BIT);
|
gl::Clear(gl::COLOR_BUFFER_BIT);
|
||||||
}
|
};
|
||||||
|
|
||||||
test_Shader.Use();
|
|
||||||
|
|
||||||
window.swap_buffers();
|
window.swap_buffers();
|
||||||
}
|
}
|
||||||
|
|
98
src/mesh.rs
98
src/mesh.rs
|
@ -1,98 +0,0 @@
|
||||||
|
|
||||||
use field_offset::offset_of;
|
|
||||||
|
|
||||||
pub struct Vertex {
|
|
||||||
Position: glm::Vec3,
|
|
||||||
Normal: glm::Vec2,
|
|
||||||
TexCoords: glm::Vec2,
|
|
||||||
Tangent: glm::Vec3,
|
|
||||||
Bitangent: glm::Vec3,
|
|
||||||
m_BoneIDs: [i32; 4],
|
|
||||||
m_Weights: [f32; 4],
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Texture {
|
|
||||||
id: u32,
|
|
||||||
Type: String,
|
|
||||||
path: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Mesh {
|
|
||||||
pub vertices: Vec<Vertex>,
|
|
||||||
pub indices: Vec<u32>,
|
|
||||||
pub textures: Vec<Texture>,
|
|
||||||
pub VAO: Option<u32>,
|
|
||||||
VBO: Option<u32>,
|
|
||||||
EBO: Option<u32>,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
impl Mesh{
|
|
||||||
pub fn new(vertices: Vec<Vertex>, indices: Vec<u32>, textures: Vec<Texture>)
|
|
||||||
{
|
|
||||||
let mut temp = Mesh {
|
|
||||||
vertices,
|
|
||||||
indices,
|
|
||||||
textures,
|
|
||||||
VAO: None,
|
|
||||||
VBO: None,
|
|
||||||
EBO: None,
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
fn setupMesh(mut temp: Mesh)
|
|
||||||
{
|
|
||||||
// create buffers/arrays
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
|
|
||||||
gl::GenVertexArrays(1, temp.VAO.as_mut().unwrap());
|
|
||||||
gl::GenBuffers(1, temp.VBO.as_mut().unwrap());
|
|
||||||
gl::GenBuffers(1, temp.EBO.as_mut().unwrap());
|
|
||||||
|
|
||||||
gl::BindVertexArray(temp.VAO.unwrap());
|
|
||||||
|
|
||||||
|
|
||||||
// NOTE, i am not sure if this one will work
|
|
||||||
gl::BindBuffer(gl::ARRAY_BUFFER, temp.VBO.unwrap());
|
|
||||||
gl::BufferData(gl::ARRAY_BUFFER, std::mem::size_of_val(&temp.vertices) as isize, temp.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 _);
|
|
||||||
|
|
||||||
// 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 _);
|
|
||||||
|
|
||||||
//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 _);
|
|
||||||
|
|
||||||
// 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 _);
|
|
||||||
|
|
||||||
// ids
|
|
||||||
gl::EnableVertexAttribArray(5);
|
|
||||||
gl::VertexAttribIPointer(5, 4, gl::INT, std::mem::size_of::<Vertex>() as i32, offset_of!(Vertex => m_BoneIDs).get_byte_offset() as *const _);
|
|
||||||
|
|
||||||
// weights
|
|
||||||
gl::EnableVertexAttribArray(6);
|
|
||||||
gl::VertexAttribPointer(6, 4, gl::FLOAT, gl::FALSE, std::mem::size_of::<Vertex>() as i32, offset_of!(Vertex => m_Weights).get_byte_offset() as *const _);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,152 @@
|
||||||
|
|
||||||
|
use image::GenericImage;
|
||||||
|
use std::path::Path;
|
||||||
|
use crate::shader::shader;
|
||||||
|
mod mesh;
|
||||||
|
use tobj;
|
||||||
|
use cgmath::{vec2, vec3};
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct Model
|
||||||
|
{
|
||||||
|
pub textures_loaded: Vec<mesh::Texture>,
|
||||||
|
pub meshes: Vec<mesh::Mesh>,
|
||||||
|
directory: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Model {
|
||||||
|
pub fn new(path: &str) -> Model {
|
||||||
|
let mut model = Model::default();
|
||||||
|
model.loadModel(path);
|
||||||
|
model
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub fn Draw(&self, shader: shader) {
|
||||||
|
for mesh in &self.meshes {
|
||||||
|
unsafe { mesh.Draw(&shader); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn loadModel(&mut self, path: &str) {
|
||||||
|
let path = Path::new(path);
|
||||||
|
|
||||||
|
|
||||||
|
self.directory = path.parent().unwrap_or_else(|| Path::new("")).to_str().unwrap().into();
|
||||||
|
let obj = tobj::load_obj(path, &tobj::LoadOptions::default());
|
||||||
|
|
||||||
|
let (models, materials) = obj.unwrap();
|
||||||
|
for model in models {
|
||||||
|
let mesh = &model.mesh;
|
||||||
|
let num_vertices = mesh.positions.len() / 3;
|
||||||
|
|
||||||
|
|
||||||
|
let mut vertices: Vec<mesh::Vertex> = Vec::with_capacity(num_vertices);
|
||||||
|
let indices: Vec<u32> = mesh.indices.clone();
|
||||||
|
|
||||||
|
let (p, n, t) = (&mesh.positions, &mesh.normals, &mesh.texcoords);
|
||||||
|
for i in 0..num_vertices {
|
||||||
|
vertices.push(mesh::Vertex {
|
||||||
|
Position: vec3(p[i*3], p[i*3+1], p[i*3+2]),
|
||||||
|
Normal: vec3(n[i*3], n[i*3+1], n[i*3+2]),
|
||||||
|
TexCoords: vec2(t[i*2], t[i*2+1]),
|
||||||
|
..mesh::Vertex::default()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// process
|
||||||
|
let mut textures = Vec::new();
|
||||||
|
if let Some(material_id) = mesh.material_id {
|
||||||
|
let material = &materials.as_ref().unwrap()[material_id];
|
||||||
|
// 1. diffuse map
|
||||||
|
//
|
||||||
|
if !material.diffuse_texture.is_empty() {
|
||||||
|
let texture = self.loadMaterialTexture(&material.diffuse_texture, "texture_diffuse");
|
||||||
|
textures.push(texture);
|
||||||
|
}
|
||||||
|
// 2.specular map
|
||||||
|
if !material.specular_texture.is_empty() {
|
||||||
|
let texture = self.loadMaterialTexture(&material.specular_texture, "texture_specular");
|
||||||
|
textures.push(texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3.normal
|
||||||
|
//
|
||||||
|
if !material.normal_texture.is_empty() {
|
||||||
|
let texture = self.loadMaterialTexture(&material.normal_texture, "texture_normal");
|
||||||
|
textures.push(texture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.meshes.push(mesh::Mesh::new(vertices,indices, textures));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn loadMaterialTexture(&mut self, path: &str, typeName: &str) -> mesh::Texture {
|
||||||
|
{
|
||||||
|
let texture = self.textures_loaded.iter().find(|t| t.path == path);
|
||||||
|
if let Some(texture) = texture {
|
||||||
|
return texture.clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let texture = mesh::Texture {
|
||||||
|
id: TextureFromFile(path),
|
||||||
|
type_: typeName.into(),
|
||||||
|
path: path.into()
|
||||||
|
};
|
||||||
|
self.textures_loaded.push(texture.clone());
|
||||||
|
texture
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fn TextureFromFile(path: &str) -> u32
|
||||||
|
{
|
||||||
|
let filename = format!("resources/models/{}", path);
|
||||||
|
|
||||||
|
let mut textureID = 0;
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
// NOTE might become a problem later on
|
||||||
|
gl::GenTextures(1, textureID as *mut u32);
|
||||||
|
gl::BindTexture(gl::TEXTURE_2D, textureID);
|
||||||
|
|
||||||
|
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_S, gl::REPEAT as i32);
|
||||||
|
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_T, gl::REPEAT as i32);
|
||||||
|
|
||||||
|
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::LINEAR as i32);
|
||||||
|
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::LINEAR as i32);
|
||||||
|
|
||||||
|
let img = image::open(Path::new(&filename)).expect("Failed to load Texture");
|
||||||
|
img.flipv();
|
||||||
|
let format = match img {
|
||||||
|
image::DynamicImage::ImageLuma8(_) => gl::RED,
|
||||||
|
image::DynamicImage::ImageLumaA8(_) => gl::RG,
|
||||||
|
image::DynamicImage::ImageRgb8(_) => gl::RGB,
|
||||||
|
image::DynamicImage::ImageRgba8(_) => gl::RGBA,
|
||||||
|
_ => panic!("What is this image u gave me big man?")
|
||||||
|
};
|
||||||
|
let data = img.as_bytes();
|
||||||
|
|
||||||
|
gl::TexImage2D(gl::TEXTURE_2D,
|
||||||
|
0,
|
||||||
|
format as i32,
|
||||||
|
img.width() as i32,
|
||||||
|
img.height() as i32,
|
||||||
|
0,
|
||||||
|
format,
|
||||||
|
gl::UNSIGNED_BYTE,
|
||||||
|
&data[0] as *const u8 as *const std::os::raw::c_void);
|
||||||
|
gl::GenerateMipmap(gl::TEXTURE_2D);
|
||||||
|
}
|
||||||
|
|
||||||
|
textureID
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,157 @@
|
||||||
|
#![allow(non_snake_case)]
|
||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
use field_offset::offset_of;
|
||||||
|
|
||||||
|
use cgmath::{Vector3, Vector2};
|
||||||
|
use cgmath::prelude::*;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -93,7 +93,7 @@ use glm;
|
||||||
unsafe {gl::UseProgram(self.ID);}
|
unsafe {gl::UseProgram(self.ID);}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO write tests for these
|
|
||||||
// BOILERPLATE JUMPSCARE
|
// BOILERPLATE JUMPSCARE
|
||||||
pub fn setBool(&self, name: &str, value: bool )
|
pub fn setBool(&self, name: &str, value: bool )
|
||||||
{unsafe {gl::Uniform1i(gl::GetUniformLocation(self.ID, name.as_ptr() as *const gl::types::GLchar), value as i32);}}
|
{unsafe {gl::Uniform1i(gl::GetUniformLocation(self.ID, name.as_ptr() as *const gl::types::GLchar), value as i32);}}
|
||||||
|
|
Loading…
Reference in New Issue