use eatgel::buffer::StaticBufferNonIndexed; use eatgel::shader::{Shader, ShaderProgram, ShaderType}; use eatgel::texture::{Image, ImageFormat, Texture, TextureSlot}; use eatgel::{GlContext, ShaderData, UpdateUniform, VertexData}; use glfw::ffi::glfwGetTime; use glfw::{ flush_messages, Action, Callback, Context, Glfw, Key, OpenGlProfileHint, SwapInterval, Window, WindowEvent, WindowHint, WindowMode, }; use nalgebra_glm as glm; use nalgebra_glm::{one, vec2, vec3, zero, Mat4, Vec2, Vec3}; use std::io::Cursor; #[derive(ShaderData)] struct Simple { model: Mat4, view: Mat4, projection: Mat4, our_texture: TextureSlot, } #[derive(VertexData)] struct Vertex { position: Vec3, uv: Vec2, } impl Default for Simple { fn default() -> Self { Simple { model: zero(), view: zero(), projection: zero(), our_texture: TextureSlot::Slot0, } } } impl Simple { pub fn new() -> Self { Self::default() } } struct State { shader_program: ShaderProgram, texture: Texture, context: GlContext, object: StaticBufferNonIndexed, size: (i32, i32), } fn init(mut context: GlContext, window: &Window) -> State { let vertex_shader = Shader::compile( ShaderType::Vertex, include_str!("../shaders/simple_vertex.glsl"), ) .expect("Failed to compile vertex shader"); let fragment_shader = Shader::compile( ShaderType::Fragment, include_str!("../shaders/simple_fragment.glsl"), ) .expect("Failed to compile fragment shader"); let mut shader_program = ShaderProgram::create_with_data(Simple::new(), vertex_shader, fragment_shader) .expect("Failed create shader program"); let vertices = vec![ Vertex { position: vec3(-0.5, -0.5, -0.5), uv: vec2(0.0, 0.0), }, Vertex { position: vec3(0.5, -0.5, -0.5), uv: vec2(1.0, 0.0), }, Vertex { position: vec3(0.5, 0.5, -0.5), uv: vec2(1.0, 1.0), }, Vertex { position: vec3(0.5, 0.5, -0.5), uv: vec2(1.0, 1.0), }, Vertex { position: vec3(-0.5, 0.5, -0.5), uv: vec2(0.0, 1.0), }, Vertex { position: vec3(-0.5, -0.5, -0.5), uv: vec2(0.0, 0.0), }, Vertex { position: vec3(-0.5, -0.5, 0.5), uv: vec2(0.0, 0.0), }, Vertex { position: vec3(0.5, -0.5, 0.5), uv: vec2(1.0, 0.0), }, Vertex { position: vec3(0.5, 0.5, 0.5), uv: vec2(1.0, 1.0), }, Vertex { position: vec3(0.5, 0.5, 0.5), uv: vec2(1.0, 1.0), }, Vertex { position: vec3(-0.5, 0.5, 0.5), uv: vec2(0.0, 1.0), }, Vertex { position: vec3(-0.5, -0.5, 0.5), uv: vec2(0.0, 0.0), }, Vertex { position: vec3(-0.5, 0.5, 0.5), uv: vec2(1.0, 0.0), }, Vertex { position: vec3(-0.5, 0.5, -0.5), uv: vec2(1.0, 1.0), }, Vertex { position: vec3(-0.5, -0.5, -0.5), uv: vec2(0.0, 1.0), }, Vertex { position: vec3(-0.5, -0.5, -0.5), uv: vec2(0.0, 1.0), }, Vertex { position: vec3(-0.5, -0.5, 0.5), uv: vec2(0.0, 0.0), }, Vertex { position: vec3(-0.5, 0.5, 0.5), uv: vec2(1.0, 0.0), }, Vertex { position: vec3(0.5, 0.5, 0.5), uv: vec2(1.0, 0.0), }, Vertex { position: vec3(0.5, 0.5, -0.5), uv: vec2(1.0, 1.0), }, Vertex { position: vec3(0.5, -0.5, -0.5), uv: vec2(0.0, 1.0), }, Vertex { position: vec3(0.5, -0.5, -0.5), uv: vec2(0.0, 1.0), }, Vertex { position: vec3(0.5, -0.5, 0.5), uv: vec2(0.0, 0.0), }, Vertex { position: vec3(0.5, 0.5, 0.5), uv: vec2(1.0, 0.0), }, Vertex { position: vec3(-0.5, -0.5, -0.5), uv: vec2(0.0, 1.0), }, Vertex { position: vec3(0.5, -0.5, -0.5), uv: vec2(1.0, 1.0), }, Vertex { position: vec3(0.5, -0.5, 0.5), uv: vec2(1.0, 0.0), }, Vertex { position: vec3(0.5, -0.5, 0.5), uv: vec2(1.0, 0.0), }, Vertex { position: vec3(-0.5, -0.5, 0.5), uv: vec2(0.0, 0.0), }, Vertex { position: vec3(-0.5, -0.5, -0.5), uv: vec2(0.0, 1.0), }, Vertex { position: vec3(-0.5, 0.5, -0.5), uv: vec2(0.0, 1.0), }, Vertex { position: vec3(0.5, 0.5, -0.5), uv: vec2(1.0, 1.0), }, Vertex { position: vec3(0.5, 0.5, 0.5), uv: vec2(1.0, 0.0), }, Vertex { position: vec3(0.5, 0.5, 0.5), uv: vec2(1.0, 0.0), }, Vertex { position: vec3(-0.5, 0.5, 0.5), uv: vec2(0.0, 0.0), }, Vertex { position: vec3(-0.5, 0.5, -0.5), uv: vec2(0.0, 1.0), }, ]; /*let data: &[f32] = &[ -0.5, -0.5, -0.5, 0.0, 0.0, 0.5, -0.5, -0.5, 1.0, 0.0, 0.5, 0.5, -0.5, 1.0, 1.0, 0.5, 0.5, -0.5, 1.0, 1.0, -0.5, 0.5, -0.5, 0.0, 1.0, -0.5, -0.5, -0.5, 0.0, 0.0, -0.5, -0.5, 0.5, 0.0, 0.0, 0.5, -0.5, 0.5, 1.0, 0.0, 0.5, 0.5, 0.5, 1.0, 1.0, 0.5, 0.5, 0.5, 1.0, 1.0, -0.5, 0.5, 0.5, 0.0, 1.0, -0.5, -0.5, 0.5, 0.0, 0.0, -0.5, 0.5, 0.5, 1.0, 0.0, -0.5, 0.5, -0.5, 1.0, 1.0, -0.5, -0.5, -0.5, 0.0, 1.0, -0.5, -0.5, -0.5, 0.0, 1.0, -0.5, -0.5, 0.5, 0.0, 0.0, -0.5, 0.5, 0.5, 1.0, 0.0, 0.5, 0.5, 0.5, 1.0, 0.0, 0.5, 0.5, -0.5, 1.0, 1.0, 0.5, -0.5, -0.5, 0.0, 1.0, 0.5, -0.5, -0.5, 0.0, 1.0, 0.5, -0.5, 0.5, 0.0, 0.0, 0.5, 0.5, 0.5, 1.0, 0.0, -0.5, -0.5, -0.5, 0.0, 1.0, 0.5, -0.5, -0.5, 1.0, 1.0, 0.5, -0.5, 0.5, 1.0, 0.0, 0.5, -0.5, 0.5, 1.0, 0.0, -0.5, -0.5, 0.5, 0.0, 0.0, -0.5, -0.5, -0.5, 0.0, 1.0, -0.5, 0.5, -0.5, 0.0, 1.0, 0.5, 0.5, -0.5, 1.0, 1.0, 0.5, 0.5, 0.5, 1.0, 0.0, 0.5, 0.5, 0.5, 1.0, 0.0, -0.5, 0.5, 0.5, 0.0, 0.0, -0.5, 0.5, -0.5, 0.0, 1.0, ];*/ let _indices: &[u32] = &[0, 1, 3, 1, 2, 3]; let object = context.create_static_buffer_non_indexed(vertices); let bytes = Cursor::new(include_bytes!("../res/eater.png").to_vec()); shader_program.init(&mut context); State { shader_program, context, object, texture: Image::load(bytes, ImageFormat::Png) .expect("Failed to load image") .into_texture(Default::default()) .expect("Failed to load as texture"), size: window.get_size(), } } fn render(state: &mut State, _glfw: &mut Glfw) { let gl = &state.context; let shader = &mut state.shader_program; let texture = &state.texture; gl.clear(); shader.enable(); texture.enable(TextureSlot::Slot0); shader.our_texture = TextureSlot::Slot0; let model = one::(); let _model = glm::rotate(&model, -55.0f32.to_radians(), &vec3(1.0f32, 0.0f32, 0.0f32)); let view = one::(); let view = glm::translate(&view, &vec3(0.0f32, 0.0f32, -3.0f32)); let projection: Mat4 = glm::perspective(45.0f32.to_radians(), 1.0, 0.1, 100.0); /*let camera_pos: Vec3 = vec3(0.0, 0.0, 3.0); let camera_target: Vec3 = vec3(0.0, 0.0, 0.0); let camera_sub: Vec3 = camera_pos - camera_target; let camera_direction: Vec3 = glm::normalize::(&camera_sub); let up = vec3(0.0, 1.0, 0.0); let camera_right = glm::normalize(&glm::cross(&up, &camera_direction)); let camera_up = glm::cross(&camera_direction, &camera_right); let view = glm::look_at( &vec3(0.0, 0.0, 0.3), &vec3(0.0, 0.0, 0.0), &vec3(0.0, 0.1, 0.0), );*/ // let trans = one::(); // let trans = glm::translate(&trans, &vec3(0.5, -0.5, 0.0f32)); unsafe { gl::Enable(gl::MULTISAMPLE); } let translates = &[ glm::vec3(0.0, 0.0, 0.0), glm::vec3(2.0, 5.0, -15.0), glm::vec3(-1.5, -2.2, -2.5), glm::vec3(-3.8, -2.0, -12.3), glm::vec3(2.4, -0.4, -3.5), glm::vec3(-1.7, 3.0, -7.5), glm::vec3(1.3, -2.0, -2.5), glm::vec3(1.5, 2.0, -2.5), glm::vec3(1.5, 0.2, -1.5), glm::vec3(-1.3, 1.0, -1.5), ]; shader.view = view; shader.projection = projection; let time = unsafe { glfwGetTime() } as f32; let radius = 10.0; let cam_x = time.sin() * radius; let cam_z = time.cos() * radius; shader.view = glm::look_at( &vec3(cam_x, 0.0, cam_z), &zero::(), &vec3(0.0, 1.0, 0.0), ); for i in 0..translates.len() { let model = one::(); let model = glm::translate(&model, &translates[i]); let angle = i as f32 * 20f32; let model = glm::rotate( &model, unsafe { glfwGetTime() } as f32 * 50.0f32.to_radians(), &vec3(0.5, 1.0, 0.0), ); shader.model = glm::rotate(&model, angle, &vec3(1.0f32, 0.3f32, 0.5f32)); shader.apply(&gl); state.object.draw(); } } fn main() { let mut glfw = glfw::init::<()>(Some(Callback { f: |err, err_str, _| { println!("{:?}: {:?}", err, err_str); }, data: (), })) .expect("Failed to init GLFW"); glfw.window_hint(WindowHint::ContextVersion(3, 3)); glfw.window_hint(WindowHint::OpenGlProfile(OpenGlProfileHint::Core)); glfw.window_hint(WindowHint::Samples(Some(4))); let (mut window, events) = glfw .create_window(500, 500, "T̶ R҉ I͜ A ͢N ͠G L̷ E̷", WindowMode::Windowed) .expect("Failed to create window"); window.make_current(); window.set_key_polling(true); glfw.set_swap_interval(SwapInterval::Adaptive); let context = GlContext::new(|x| window.get_proc_address(x)); let mut state = init(context, &window); unsafe { gl::Viewport(0, 0, state.size.0, state.size.1); gl::Enable(gl::DEPTH_TEST); } // let mut time = Instant::now(); // println!("0"); while !window.should_close() { let (width, height) = window.get_size(); if state.size != (width, height) { unsafe { gl::Viewport(0, 0, width, height) } } state.size = (width, height); render(&mut state, &mut glfw); window.swap_buffers(); glfw.poll_events(); for (_, event) in flush_messages(&events) { if let WindowEvent::Key(key, _, Action::Release, _) = event { if key == Key::Escape || key == Key::Q { window.set_should_close(true); } } } // // let new_time = Instant::now(); // println!( // "\x1B[1A\x1B[Kfps: {}", // (1.0 / (new_time - time).as_secs_f64()).floor() // ); // // time = new_time; } window.close(); }