summaryrefslogtreecommitdiff
path: root/source/dw/app/getshdprg.rs
blob: 76eb5cf0a11065daeb8f939d4d1e433e11e4210e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
// Copyright 2023 Gabriel Jensen.

use crate::dw::{app::App,datpth};

extern crate gl;

use gl::{AttachShader,COMPILE_STATUS,CompileShader,COMPUTE_SHADER,CreateProgram,CreateShader,DeleteShader,FALSE,FRAGMENT_SHADER,GEOMETRY_SHADER,GetShaderInfoLog,GetShaderiv,INFO_LOG_LENGTH,LinkProgram,ShaderSource,TESS_CONTROL_SHADER,TESS_EVALUATION_SHADER,VERTEX_SHADER};
use gl::types::{GLchar,GLenum,GLint,GLsizei,GLuint};
use libc::{STDERR_FILENO,write};
use std::alloc::{alloc,dealloc,Layout};
use std::ffi::c_void;
use std::ptr::{addr_of,null};

impl App {
	pub fn getshdprg(&mut self) -> GLuint {
		eprintln!("compiling shaders");

		let cmpshd = |nam: & str| -> GLuint {
			let extoff = nam.find('.').expect("unable to find file extension seperator")+0x1;
			let filext = &nam[extoff..];
			let typ = match filext {
				"comp" => COMPUTE_SHADER,
				"frag" => FRAGMENT_SHADER,
				"geom" => GEOMETRY_SHADER,
				"tesc" => TESS_CONTROL_SHADER,
				"tese" => TESS_EVALUATION_SHADER,
				"vert" => VERTEX_SHADER,
				_      => panic!("invalid shader file extension \"{}\"",filext),
			};

			let typstr = match typ {
				FRAGMENT_SHADER => "fragment",
				VERTEX_SHADER   => "vertex",
				_               => unreachable!(),
			};

			let filext = match typ {
				FRAGMENT_SHADER => "frag",
				VERTEX_SHADER   => "vert",
				_               => unreachable!(),
			};

			eprintln!("compiling {} shader \"{}\"",typstr,nam);

			//let src = read(pth).expect("unable to read shader at");
			let src = match nam {
				"main.frag" => include_bytes!("shader/main.frag.glsl").to_vec(),
				"main.vert" => include_bytes!("shader/main.vert.glsl").to_vec(),
				_           => panic!("shader not found"),
			};

			unsafe {
				let shd    = CreateShader(typ);
				let srcptr = src.as_ptr();
				ShaderSource(shd,0x1,addr_of!(srcptr) as *const *const GLchar,null::<GLint>());

				CompileShader(shd);

				let mut sts:GLint = 0x0;
				GetShaderiv(shd,COMPILE_STATUS,&mut sts);
				if sts == FALSE as GLint {
					let mut len: GLint = 0x0;
					GetShaderiv(shd,INFO_LOG_LENGTH,&mut len);
					
					let lay = Layout::from_size_align(len as usize,0x1).unwrap();

					let log = alloc(lay);
					GetShaderInfoLog(shd,len,null::<GLsizei>() as *mut GLsizei,log as *mut GLchar);

					eprint!("unable able to compile shader:\n");
					write(STDERR_FILENO,log as *const c_void,len as usize);
					eprintln!();

					dealloc(log,lay);

					panic!("unable to compile shader");
				}

				return shd;
			}
		};

		let frgshd = cmpshd("main.frag");
		let vtxshd = cmpshd("main.vert");
		
		unsafe {
			let prg = CreateProgram();
			AttachShader(prg,frgshd);
			AttachShader(prg,vtxshd);
			LinkProgram(prg);

			DeleteShader(frgshd);
			DeleteShader(vtxshd);

			return prg;
		}
	}
}