Compare commits

...

5 Commits

Author SHA1 Message Date
meishibiezb
2d97d7a01f feat: 初步定义vao 2026-03-06 02:06:19 +08:00
meishibiezb
91fb640d37 feat: 传入uniform 2026-03-05 03:46:00 +08:00
meishibiezb
eeb3d016c8 feat: 添加Shader类和Program类 2026-03-05 02:59:52 +08:00
meishibiezb
0dcd45ddc7 fixed: 更改着色器名称 2026-03-05 02:08:46 +08:00
meishibiezb
3420f1348d fixed: 修复着色器编译问题 2026-03-05 01:22:04 +08:00
6 changed files with 234 additions and 10 deletions

View File

@@ -1 +1,3 @@
pub mod render_timer;
pub mod shader;
pub mod vao;

View File

@@ -33,28 +33,30 @@ fn main() {
let mut render_timer = RenderTimer::new();
// 编译着色器
let vs_src = include_bytes!(".\\shaders\\vs.glsl");
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 {
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_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 {
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) };
@@ -68,7 +70,7 @@ fn main() {
unsafe { gl::LinkProgram(sp) };
let mut success = 0;
unsafe { gl::GetProgramiv(sp, gl::LINK_STATUS, &mut success) };
if success != 0 {
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) };
@@ -86,7 +88,9 @@ fn main() {
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 a: [f32; _] = [
0.5, 0.5, 0.0, 0.5, -0.5, 0.0, -0.5, -0.5, 0.0, -0.5, 0.5, 0.0,
];
let mut vbo: u32 = 0;
unsafe { gl::GenBuffers(1, &mut vbo) };
unsafe { gl::BindBuffer(gl::ARRAY_BUFFER, vbo) };
@@ -112,6 +116,20 @@ fn main() {
};
unsafe { gl::EnableVertexAttribArray(0) };
// 创建EBO
let b: [u32; _] = [0, 1, 3, 1, 2, 3];
let mut ebo = 0;
unsafe { gl::GenBuffers(1, &mut ebo) };
unsafe { gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, ebo) };
unsafe {
gl::BufferData(
gl::ELEMENT_ARRAY_BUFFER,
size_of_val(&b) as _,
b.as_ptr() as _,
gl::STATIC_DRAW,
)
};
// 渲染循环
while !window.should_close() {
glfw.poll_events();
@@ -119,7 +137,7 @@ fn main() {
handle_window_event(&mut window, event);
}
render(&mut render_timer, sp ,vao);
render(&mut render_timer, sp, vao);
window.swap_buffers();
}
@@ -133,11 +151,23 @@ fn handle_window_event(window: &mut glfw::Window, event: glfw::WindowEvent) {
}
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) };
// 向着色器传入颜色
let location = unsafe { gl::GetUniformLocation(sp, "inColor".as_ptr() as _) };
unsafe { gl::Uniform4f(location, t.cos() * 0.5 + 1.0, t.sin() * 0.5 + 1.0, 0.7, 1.0) };
// 绘制图形
unsafe { gl::UseProgram(sp) };
unsafe { gl::BindVertexArray(vao) };
unsafe { gl::DrawArrays(gl::TRIANGLES, 0, 3) };
if (t as u32) % 2 == 1 {
unsafe { gl::PolygonMode(gl::FRONT_AND_BACK, gl::LINE) };
}
else {
unsafe { gl::PolygonMode(gl::FRONT_AND_BACK, gl::FILL) };
}
unsafe { gl::DrawElements(gl::TRIANGLES, 6, gl::UNSIGNED_INT, null()) };
}

86
src/shader.rs Normal file
View File

@@ -0,0 +1,86 @@
use std::{
ptr::{null, null_mut},
str::from_utf8,
};
use gl::{CompileShader, ShaderSource};
pub struct Shader {
id: gl::types::GLuint,
}
impl Shader {
pub fn new(src: &str, type_: gl::types::GLenum) -> Result<Self, Box<dyn std::error::Error>> {
// 编译着色器
let id = unsafe { gl::CreateShader(type_) };
let c_src = std::ffi::CString::new(src)?;
unsafe { ShaderSource(id, 1, &c_src.as_ptr() as _, null()) };
unsafe { CompileShader(id) };
// 检查编译是否成功
let mut success = 0;
unsafe { gl::GetShaderiv(id, gl::COMPILE_STATUS, &mut success) };
if success == 0 {
let mut log = [0; 512];
unsafe { gl::GetShaderInfoLog(id, 512, core::ptr::null_mut(), log.as_mut_ptr()) };
let log_u8: [u8; 512] = unsafe { std::mem::transmute(log) };
let e = from_utf8(&log_u8)?;
return Err(e.into());
}
Ok(Shader { id: id })
}
}
impl Drop for Shader {
fn drop(&mut self) {
unsafe {
gl::DeleteShader(self.id);
}
}
}
pub struct Program {
id: gl::types::GLuint,
}
impl Program {
pub fn new() -> Self {
let id = unsafe { gl::CreateProgram() };
Program { id: id }
}
pub fn attach_shader(&self, shader: &Shader) {
unsafe { gl::AttachShader(self.id, shader.id) };
}
pub fn link_program(&self) -> Result<(), Box<dyn std::error::Error>> {
// 链接着色器
unsafe { gl::LinkProgram(self.id) };
// 检查链接是否成功
let mut success = 0;
unsafe { gl::GetProgramiv(self.id, gl::LINK_STATUS, &mut success) };
if success == 0 {
let mut log = [0; 512];
unsafe { gl::GetProgramInfoLog(self.id, 512, null_mut(), log.as_mut_ptr()) };
let log_u8: [u8; 512] = unsafe { std::mem::transmute(log) };
let e = from_utf8(&log_u8)?;
return Err(e.into());
}
Ok(())
}
pub fn use_program(&self) {
unsafe { gl::UseProgram(self.id) };
}
}
impl Drop for Program {
fn drop(&mut self) {
unsafe {
gl::DeleteProgram(self.id);
}
}
}

View File

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

104
src/vao.rs Normal file
View File

@@ -0,0 +1,104 @@
use std::os::raw::c_void;
pub struct EBO {
id: gl::types::GLuint,
}
impl EBO {
pub fn new(data: &[u32]) -> Self {
let mut id = 0;
unsafe { gl::GenBuffers(1, &mut id) };
unsafe { gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, id) };
unsafe {
gl::BufferData(
gl::ELEMENT_ARRAY_BUFFER,
size_of_val(&data) as _,
data.as_ptr() as _,
gl::STATIC_DRAW,
)
};
EBO { id: id }
}
pub fn bind(&self) {
unsafe { gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, self.id) };
}
}
pub struct VBO {
id: gl::types::GLuint,
}
impl VBO {
pub fn new(data: &[u32]) -> Self {
let mut id: u32 = 0;
unsafe { gl::GenBuffers(1, &mut id) };
unsafe { gl::BindBuffer(gl::ARRAY_BUFFER, id) };
unsafe {
gl::BufferData(
gl::ARRAY_BUFFER,
size_of_val(&data) as _,
data.as_ptr() as _,
gl::STATIC_DRAW,
)
};
VBO { id: id }
}
pub fn bind(&self) {
unsafe { gl::BindBuffer(gl::ARRAY_BUFFER, self.id) };
}
pub fn add_attrib(// TODO: 迁移到其他地方
&self,
index: u32,
size: i32,
type_: u32,
normalized: u8,
stride: i32,
pointer: *const c_void,
) {
self.bind();
unsafe { gl::VertexAttribPointer(index, size, type_, normalized, stride, pointer) };
unsafe { gl::EnableVertexAttribArray(index) };
}
}
pub struct VAO {
id: gl::types::GLuint,
vbo: Option<VBO>,
ebo: Option<EBO>,
}
impl VAO {
pub fn new() -> Self {
let mut id = 0;
unsafe { gl::GenVertexArrays(1, &mut id) };
unsafe { gl::BindVertexArray(id) };
VAO { id: id, vbo: None, ebo: None }
}
pub fn bind(&self) {
unsafe { gl::BindVertexArray(self.id) };
}
pub fn new_vbo(&mut self, data:&[u32]) {
self.bind();
self.vbo = Some(VBO::new(data));
}
pub fn new_ebo(&mut self, data:&[u32]) {
self.bind();
self.ebo = Some(EBO::new(data));
}
}
pub struct VertexAttribute {
// TODO: 定义
}