1use std::{fs::File, io::Read};
2
3use crate::{
4 debug::log,
5 errors::{GraphicsError, GraphicsResult},
6};
7
8#[allow(missing_docs)]
9#[derive(Debug)]
10pub enum ShaderStage {
11 Vertex,
12 Fragment,
13 Geometry,
14 Tesselate,
15 Compute,
16}
17
18#[allow(missing_docs)]
19pub struct Shader {
20 pub(crate) stage: ShaderStage,
21 pub(crate) code: Vec<u32>,
22}
23
24impl Shader {
25 pub fn open(path: &str, stage: ShaderStage) -> GraphicsResult<Self> {
33 let mut file = match File::open(path) {
34 Ok(file) => file,
35 Err(e) => {
36 log!("cannot open file: {}", e);
37 return Err(GraphicsError::ShaderError);
38 }
39 };
40
41 let size = file.metadata().unwrap().len() as usize;
42
43 let mut shader_code_bytes = Vec::<u8>::with_capacity(size);
44
45 match file.read_to_end(&mut shader_code_bytes) {
46 Ok(_) => unsafe {
47 shader_code_bytes.set_len(size);
48 },
49 Err(e) => {
50 log!("cannot read file: {}", e);
51 return Err(GraphicsError::ShaderError);
52 }
53 };
54
55 let shader_code = unsafe {
56 let ptr = std::alloc::alloc(std::alloc::Layout::from_size_align_unchecked(size, 0x10))
57 as *mut u8;
58
59 if ptr.is_null() {
60 panic!("Failed to allocate memory");
61 }
62
63 std::slice::from_raw_parts_mut(ptr, size).copy_from_slice(std::slice::from_raw_parts(
64 shader_code_bytes.as_ptr(),
65 shader_code_bytes.len(),
66 ));
67
68 let len = size / 4;
69
70 Vec::from_raw_parts(ptr as *mut u32, len, len)
71 };
72
73 Ok(Shader {
74 stage,
75 code: shader_code,
76 })
77 }
78}