init
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/target
|
||||
1145
Cargo.lock
generated
Normal file
1145
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
8
Cargo.toml
Normal file
8
Cargo.toml
Normal 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
1
src/lib.rs
Normal file
@@ -0,0 +1 @@
|
||||
pub mod render_timer;
|
||||
143
src/main.rs
Normal file
143
src/main.rs
Normal 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
25
src/render_timer.rs
Normal 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
7
src/shaders/fs.glsl
Normal 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
7
src/shaders/vs.glsl
Normal 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);
|
||||
}
|
||||
Reference in New Issue
Block a user