146 lines
4.7 KiB
Rust
146 lines
4.7 KiB
Rust
use std::{
|
|
ptr::{null, null_mut},
|
|
str::from_utf8,
|
|
};
|
|
|
|
use glfw::{Action, Context, Key};
|
|
use learn_gl::render_timer::RenderTimer;
|
|
fn main() {
|
|
let default_width = 500;
|
|
let default_height = 500;
|
|
|
|
let mut glfw = glfw::init(glfw::fail_on_errors).expect("msg");
|
|
let (mut window, events) = glfw
|
|
.create_window(
|
|
default_width,
|
|
default_height,
|
|
"learn_gl",
|
|
glfw::WindowMode::Windowed,
|
|
)
|
|
.expect("msg");
|
|
|
|
window.set_key_polling(true);
|
|
window.make_current();
|
|
|
|
gl::load_with(|s| glfw.get_proc_address_raw(s).unwrap() as *const _);
|
|
// gl::load_with(|s| window.get_proc_address(s).unwrap() as *const _);
|
|
|
|
unsafe { gl::Viewport(0, 0, default_width as _, default_height as _) };
|
|
window.set_framebuffer_size_callback(|_windows, width, height| {
|
|
unsafe { gl::Viewport(0, 0, width as _, height as _) };
|
|
});
|
|
|
|
let mut render_timer = RenderTimer::new();
|
|
|
|
// 编译着色器
|
|
let vs_src = std::ffi::CString::new(include_str!(".\\shaders\\vs.vert")).unwrap_or_default();
|
|
println!("Vs Shader:\n{}", vs_src.to_str().unwrap_or_default());
|
|
let vs_ptr = vs_src.as_ptr() as *const i8;
|
|
let vs = unsafe { gl::CreateShader(gl::VERTEX_SHADER) };
|
|
unsafe { gl::ShaderSource(vs, 1, &vs_ptr as _, null()) };
|
|
unsafe { gl::CompileShader(vs) };
|
|
let mut success = 0;
|
|
unsafe { gl::GetShaderiv(vs, gl::COMPILE_STATUS, &mut success) };
|
|
if success == 0 {
|
|
let mut log = [0; 512];
|
|
unsafe { gl::GetShaderInfoLog(vs, 512, core::ptr::null_mut(), log.as_mut_ptr()) };
|
|
let log_u8: [u8; 512] = unsafe { std::mem::transmute(log) };
|
|
println!("{}", from_utf8(&log_u8).unwrap());
|
|
}
|
|
|
|
let fs_src = std::ffi::CString::new(include_str!(".\\shaders\\fs.frag")).unwrap_or_default();
|
|
println!("Fs Shader:\n{}", fs_src.to_str().unwrap_or_default());
|
|
let fs_ptr = fs_src.as_ptr() as *const i8;
|
|
let fs = unsafe { gl::CreateShader(gl::FRAGMENT_SHADER) };
|
|
unsafe { gl::ShaderSource(fs, 1, &fs_ptr as _, null()) };
|
|
unsafe { gl::CompileShader(fs) };
|
|
let mut success = 0;
|
|
unsafe { gl::GetShaderiv(fs, gl::COMPILE_STATUS, &mut success) };
|
|
if success == 0 {
|
|
let mut log = [0; 512];
|
|
unsafe { gl::GetShaderInfoLog(fs, 512, core::ptr::null_mut(), log.as_mut_ptr()) };
|
|
let log_u8: [u8; 512] = unsafe { std::mem::transmute(log) };
|
|
println!("{}", from_utf8(&log_u8).unwrap());
|
|
}
|
|
|
|
// 链接着色器
|
|
let sp = unsafe { gl::CreateProgram() };
|
|
unsafe { gl::AttachShader(sp, vs) };
|
|
unsafe { gl::AttachShader(sp, fs) };
|
|
unsafe { gl::LinkProgram(sp) };
|
|
let mut success = 0;
|
|
unsafe { gl::GetProgramiv(sp, gl::LINK_STATUS, &mut success) };
|
|
if success == 0 {
|
|
let mut log = [0; 512];
|
|
unsafe { gl::GetProgramInfoLog(sp, 512, null_mut(), log.as_mut_ptr()) };
|
|
let log_u8: [u8; 512] = unsafe { std::mem::transmute(log) };
|
|
println!("{}", from_utf8(&log_u8).unwrap());
|
|
}
|
|
|
|
// 使用程序和删除着色器
|
|
unsafe { gl::UseProgram(sp) };
|
|
unsafe { gl::DeleteShader(vs) };
|
|
unsafe { gl::DeleteShader(fs) };
|
|
|
|
// 创建VAO
|
|
let mut vao = 0;
|
|
unsafe { gl::GenVertexArrays(1, &mut vao) };
|
|
unsafe { gl::BindVertexArray(vao) };
|
|
|
|
// 创建VBO
|
|
let a: [f32; _] = [-0.5, -0.5, 0.0, 0.5, -0.5, 0.0, 0.0, 0.5, 0.0];
|
|
let mut vbo: u32 = 0;
|
|
unsafe { gl::GenBuffers(1, &mut vbo) };
|
|
unsafe { gl::BindBuffer(gl::ARRAY_BUFFER, vbo) };
|
|
unsafe {
|
|
gl::BufferData(
|
|
gl::ARRAY_BUFFER,
|
|
size_of_val(&a) as _,
|
|
a.as_ptr() as _,
|
|
gl::STATIC_DRAW,
|
|
)
|
|
};
|
|
|
|
// 链接顶点属性
|
|
unsafe {
|
|
gl::VertexAttribPointer(
|
|
0,
|
|
3,
|
|
gl::FLOAT,
|
|
gl::FALSE,
|
|
(3 * size_of::<f32>()) as _,
|
|
0 as _,
|
|
)
|
|
};
|
|
unsafe { gl::EnableVertexAttribArray(0) };
|
|
|
|
// 渲染循环
|
|
while !window.should_close() {
|
|
glfw.poll_events();
|
|
for (_, event) in glfw::flush_messages(&events) {
|
|
handle_window_event(&mut window, event);
|
|
}
|
|
|
|
render(&mut render_timer, sp ,vao);
|
|
|
|
window.swap_buffers();
|
|
}
|
|
}
|
|
|
|
fn handle_window_event(window: &mut glfw::Window, event: glfw::WindowEvent) {
|
|
match event {
|
|
glfw::WindowEvent::Key(Key::Escape, _, Action::Press, _) => window.set_should_close(true),
|
|
_ => {}
|
|
}
|
|
}
|
|
|
|
fn render(render_timer: &mut RenderTimer, sp: u32, vao: u32) {
|
|
let t = render_timer.time_count() as f32 / 1000.0 as f32;
|
|
unsafe { gl::ClearColor(t.sin() * 0.5 + 1.0, t.cos() * 0.5 + 1.0, 0.3, 1.0) };
|
|
unsafe { gl::Clear(gl::COLOR_BUFFER_BIT) };
|
|
|
|
unsafe { gl::UseProgram(sp) };
|
|
unsafe { gl::BindVertexArray(vao) };
|
|
unsafe { gl::DrawArrays(gl::TRIANGLES, 0, 3) };
|
|
}
|