This commit is contained in:
meishibiezb
2026-03-03 01:37:15 +08:00
commit e7a3d1c064
8 changed files with 1337 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/target

1145
Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

8
Cargo.toml Normal file
View File

@@ -0,0 +1,8 @@
[package]
name = "learn_gl"
version = "0.1.0"
edition = "2024"
[dependencies]
gl = "0.14.0"
glfw = "0.61.0"

1
src/lib.rs Normal file
View File

@@ -0,0 +1 @@
pub mod render_timer;

143
src/main.rs Normal file
View File

@@ -0,0 +1,143 @@
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 = include_bytes!(".\\shaders\\vs.glsl");
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 = include_bytes!(".\\shaders\\fs.glsl");
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) };
}

25
src/render_timer.rs Normal file
View File

@@ -0,0 +1,25 @@
use std::time::Instant;
pub struct RenderTimer {
create_time: Instant,
last_check: Instant,
}
impl RenderTimer {
pub fn new() -> Self {
RenderTimer {
create_time: std::time::Instant::now(),
last_check: Instant::now(),
}
}
pub fn time_count(&mut self) -> u128 {
self.create_time.elapsed().as_millis()
}
pub fn elapsed(&mut self) -> u128 {
let elapsed = self.last_check.elapsed();
self.last_check = Instant::now();
elapsed.as_millis()
}
}

7
src/shaders/fs.glsl Normal file
View File

@@ -0,0 +1,7 @@
#version 330 core
out vec4 FragColor;
void main()
{
FragColor = vec4(0.0f, 0.0f, 0.0f, 1.0f);
}

7
src/shaders/vs.glsl Normal file
View File

@@ -0,0 +1,7 @@
#version 330 core
layout (location = 0) in vec3 aPos;
void main()
{
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
}