You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

395 lines
11 KiB
Rust

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<Simple>,
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::<Mat4>();
let _model = glm::rotate(&model, -55.0f32.to_radians(), &vec3(1.0f32, 0.0f32, 0.0f32));
let view = one::<Mat4>();
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::<f32, U3>(&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::<Mat4>();
// 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>(),
&vec3(0.0, 1.0, 0.0),
);
for i in 0..translates.len() {
let model = one::<Mat4>();
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();
}