Files
learn_gl/src/main.rs
2026-03-05 02:08:46 +08:00

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