diff --git a/src/consts.rs b/src/consts.rs index f068edd..d9df4e5 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -9,11 +9,13 @@ layout (location = 1) in vec2 aTexCoord; out vec2 TexCoord; -uniform mat4 transform; +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; void main() { - gl_Position = transform * vec4(aPos, 1.0); + gl_Position = projection * view * model * vec4(aPos, 1.0); TexCoord = vec2(aTexCoord.x, aTexCoord.y); } "#; diff --git a/src/macros.rs b/src/macros.rs index 6de3dba..6a8ac30 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -10,6 +10,7 @@ macro_rules! c_str { /// Get offset to struct member, similar to `offset_of` in C/C++ /// From https://stackoverflow.com/questions/40310483/how-to-get-pointer-offset-in-bytes/40310851#40310851 +#[allow(unused_macros)] macro_rules! offset_of { ($ty:ty, $field:ident) => { &(*(ptr::null() as *const $ty)).$field as *const _ as usize diff --git a/src/main.rs b/src/main.rs index faae8da..abf2273 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,7 +8,6 @@ use std::ffi::CString; use std::mem; use std::os::raw::c_void; use std::ptr; -use std::str; use std::sync::mpsc::Receiver; use std::path::Path; @@ -17,7 +16,7 @@ extern crate image; use image::GenericImage; use cgmath::prelude::*; -use cgmath::{vec3, Matrix4, Rad}; +use cgmath::{perspective, vec3, Deg, Matrix4}; mod consts; mod macros; @@ -159,7 +158,9 @@ pub fn main() { let color_r = 0.188; let color_g = 0.22; let color_b = 0.235; + let mut view_modifier = 0.5; while !window.should_close() { + view_modifier = (view_modifier + 0.01) % 1.9; // events // ----- process_events(&mut window, &events); @@ -171,16 +172,24 @@ pub fn main() { gl::Clear(gl::COLOR_BUFFER_BIT); gl::BindTexture(gl::TEXTURE_2D, texture); - // create transformations - let mut transform: Matrix4 = Matrix4::identity(); - transform = transform * Matrix4::::from_translation(vec3(0.5, -0.5, 0.0)); - transform = transform * Matrix4::::from_angle_z(Rad(glfw.get_time() as f32)); - - // get matrix's uniform location and set matrix shader_object.useProgram(); - let transform_loc = - gl::GetUniformLocation(shader_object.ID, c_str!("transform").as_ptr()); - gl::UniformMatrix4fv(transform_loc, 1, gl::FALSE, transform.as_ptr()); + // create transformations + let model: Matrix4 = Matrix4::from_angle_x(Deg(-55.)); + let view: Matrix4 = Matrix4::from_translation(vec3(0., 0., -3. + view_modifier)); + let projection: Matrix4 = perspective( + Deg(45.0), + consts::SCR_WIDTH as f32 / consts::SCR_HEIGHT as f32, + 0.1, + 100.0, + ); + // retrieve the matrix uniform locations + let model_location = gl::GetUniformLocation(shader_object.ID, c_str!("model").as_ptr()); + let view_loc = gl::GetUniformLocation(shader_object.ID, c_str!("view").as_ptr()); + // pass them to the shaders (3 different ways) + gl::UniformMatrix4fv(model_location, 1, gl::FALSE, model.as_ptr()); + gl::UniformMatrix4fv(view_loc, 1, gl::FALSE, &view[0][0]); + // note: currently we set the projection matrix each frame, but since the projection matrix rarely changes it's often best practice to set it outside the main loop only once. + shader_object.setMat4(c_str!("projection"), &projection); gl::BindVertexArray(vao); // seeing as we only have a single VAO there's no need to bind it every time, but we'll do so to keep things a bit more organized gl::DrawElements(gl::TRIANGLES, 6, gl::UNSIGNED_INT, ptr::null()); @@ -191,6 +200,12 @@ pub fn main() { window.swap_buffers(); glfw.poll_events(); } + + unsafe { + gl::DeleteVertexArrays(1, &vao); + gl::DeleteBuffers(1, &vbo); + gl::DeleteBuffers(1, &ebo); + } } // NOTE: not the same version as in common.rs!