diff --git a/src/lib.rs b/src/lib.rs index 7c6863a..050038d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1 +1,2 @@ -pub mod render_timer; \ No newline at end of file +pub mod render_timer; +pub mod shader; \ No newline at end of file diff --git a/src/shader.rs b/src/shader.rs new file mode 100644 index 0000000..7d0e426 --- /dev/null +++ b/src/shader.rs @@ -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> { + // 编译着色器 + 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> { + // 链接着色器 + 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); + } + } +}