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
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();
|
|
}
|