diff --git a/Cargo.toml b/Cargo.toml index 84eaee4..0c37c9b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,3 +8,5 @@ edition = "2021" [dependencies] gl = "0.14.0" glfw = "0.51.0" +glm = "0.2.3" +stb = { version = "0.3.2", default-features = false, features = ["stb_image"] } diff --git a/resources/shaders/basic/shader.frag b/resources/shaders/basic/shader.frag new file mode 100644 index 0000000..1978ae3 --- /dev/null +++ b/resources/shaders/basic/shader.frag @@ -0,0 +1,6 @@ +#version 330 core + out vec4 Color; + void main() + { + Color = vec4(0.9, 0.5, 0.2, 1.0); + } diff --git a/resources/shaders/basic/shader.vert b/resources/shaders/basic/shader.vert new file mode 100644 index 0000000..90ff35c --- /dev/null +++ b/resources/shaders/basic/shader.vert @@ -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); + } diff --git a/src/main.rs b/src/main.rs index a04d041..fb8cf42 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,6 +20,8 @@ fn main() { glfw.window_hint(glfw::WindowHint::OpenGlProfile(glfw::OpenGlProfileHint::Core)); glfw.window_hint(glfw::WindowHint::OpenGlForwardCompat(true)); glfw.window_hint(glfw::WindowHint::Resizable(false)); + glfw.window_hint(glfw::WindowHint::TransparentFramebuffer(true)); + glfw.window_hint(glfw::WindowHint::Decorated(true)); //create window @@ -37,18 +39,58 @@ fn main() { gl::ClearColor(0.4, 0.4, 0.4, 1.0); } + + // put biggie thingies here + let vertices = [ + -0.5f32, -0.5, 0.0, + 0.5, -0.5, 0.0, + 0.0, 0.5, 0.0, + ]; + + let mut vao = 0; + unsafe { gl::GenVertexArrays(1, &mut vao)}; + + let mut vbo = 0; + unsafe{gl::GenBuffers(1, &mut vbo)}; + + unsafe { + gl::BindVertexArray(vao); + + gl::BindBuffer(gl::ARRAY_BUFFER, vbo); + gl::BufferData(gl::ARRAY_BUFFER, std::mem::size_of_val(&vertices) as isize, vertices.as_ptr().cast(), gl::STATIC_DRAW); + + gl::VertexAttribPointer(0, 3, gl::FLOAT, gl::FALSE, 3 * std::mem::size_of::() as i32, 0 as *const _); + gl::EnableVertexAttribArray(0); + + gl::BindBuffer(gl::ARRAY_BUFFER, 0); + gl::BindVertexArray(0); + + } + + let mut test_Shader = shader::shader::new("basic"); + + // NOTE window loop while !window.should_close() { glfw.poll_events(); for (_, event) in glfw::flush_messages(&events) { glfw_handle_event(&mut window, event); } - clear_color(0.3, 0.4, 0.6, 1.0); + clear_color(0.1, 0.1, 0.1, 0.0); unsafe { gl::Clear(gl::COLOR_BUFFER_BIT); } + test_Shader.Use(); + + unsafe { + gl::BindVertexArray(vao); + + gl::DrawArrays(gl::TRIANGLES, 0, 3); + + gl::BindVertexArray(0); + } window.swap_buffers(); } diff --git a/src/shader.rs b/src/shader.rs index c1aad83..252265a 100644 --- a/src/shader.rs +++ b/src/shader.rs @@ -1,6 +1,7 @@ use gl; use std::fs; +use glm; /// Shader Struct for creating and using shaders in the Context of engine /// pub struct shader { @@ -18,8 +19,6 @@ use std::fs; /// `new(String::from("Example"))` /// if the String given was "Example" the Program expects both shaders to be in the directory "resources/shaders/Example/" /// with the vertex shader being called "shader.vert" and fragment "shader.frag" - /// # TODO - /// add a way to interact with uniforms pub fn new(path: &str) -> shader { //read file contents @@ -94,7 +93,67 @@ use std::fs; unsafe {gl::UseProgram(self.ID);} } + // TODO write tests for these + // BOILERPLATE JUMPSCARE + 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);}} + pub fn setInt(&self, name: &str, value: u32 ) + {unsafe {gl::Uniform1i(gl::GetUniformLocation(self.ID, name.as_ptr() as *const gl::types::GLchar), value as i32);}} + pub fn setFloat(&self, name: &str, value: f32 ) + {unsafe {gl::Uniform1f(gl::GetUniformLocation(self.ID, name.as_ptr() as *const gl::types::GLchar), value as f32);}} + pub fn setVec2(&self, name: &str, value: glm::Vec2 ) + {unsafe {gl::Uniform2fv(gl::GetUniformLocation(self.ID, name.as_ptr() as *const gl::types::GLchar), 1, &value[0]);}} + pub fn setVec2d(&self, name: &str, x: f32, y: f32) + {unsafe {gl::Uniform2f(gl::GetUniformLocation(self.ID, name.as_ptr() as *const gl::types::GLchar), x, y);}} + pub fn setVec3(&self, name: &str, value: glm::Vec3 ) + {unsafe {gl::Uniform3fv(gl::GetUniformLocation(self.ID, name.as_ptr() as *const gl::types::GLchar), 1, &value[0]);}} + pub fn setVec3d(&self, name: &str, x: f32, y: f32, z: f32 ) + {unsafe {gl::Uniform3f(gl::GetUniformLocation(self.ID, name.as_ptr() as *const gl::types::GLchar), x, y, z);}} + pub fn setVec4(&self, name: &str, value: glm::Vec4 ) + {unsafe {gl::Uniform4fv(gl::GetUniformLocation(self.ID, name.as_ptr() as *const gl::types::GLchar), 1, &value[0]);}} + pub fn setVec4d(&self, name: &str, x: f32, y: f32, z: f32, w: f32) + {unsafe {gl::Uniform4f(gl::GetUniformLocation(self.ID, name.as_ptr() as *const gl::types::GLchar), x, y, z, w);}} + pub fn setMat2(&self, name: &str, value: glm::Mat2) + {unsafe {gl::UniformMatrix2fv(gl::GetUniformLocation(self.ID, name.as_ptr() as *const gl::types::GLchar), 1, gl::FALSE, &value[0][0]);}} + pub fn setMat3(&self, name: &str, value: glm::Mat3) + {unsafe {gl::UniformMatrix3fv(gl::GetUniformLocation(self.ID, name.as_ptr() as *const gl::types::GLchar), 1, gl::FALSE, &value[0][0]);}} + pub fn setMat4(&self, name: &str, value: glm::Mat4) + {unsafe {gl::UniformMatrix4fv(gl::GetUniformLocation(self.ID, name.as_ptr() as *const gl::types::GLchar), 1, gl::FALSE, &value[0][0]);}} + } + +#[cfg(test)] + mod tests { + use glfw; + use glfw::Context; + use gl; + use super::*; + + #[test] + fn ShaderLoading() { + + // initialize GLFW + let mut glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap(); + // set window hints + glfw.window_hint(glfw::WindowHint::ContextVersion(3, 3)); + glfw.window_hint(glfw::WindowHint::OpenGlProfile(glfw::OpenGlProfileHint::Core)); + glfw.window_hint(glfw::WindowHint::OpenGlForwardCompat(true)); + glfw.window_hint(glfw::WindowHint::Resizable(false)); + + //create Window + let (mut window, events) = glfw.create_window(480, 320, "Shader Test", glfw::WindowMode::Windowed).unwrap(); + let (screen_width, screen_height) = window.get_framebuffer_size(); + + // setup window + window.make_current(); + window.set_key_polling(true); + // initialize gl + gl::load_with(|ptr| window.get_proc_address(ptr) as *const _); + + let Shader = shader::new("basic"); + Shader.Use(); + } + }