summaryrefslogtreecommitdiff
path: root/source/dw/app/getshdprg.rs
blob: 2e02ff82b5523aed5e8c2bc1e7532bfd11db8876 (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
// Copyright 2023 Gabriel Jensen.

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

extern crate gl;

use gl::{AttachShader,COMPILE_STATUS,CompileShader,CreateProgram,CreateShader,DeleteShader,FALSE,FRAGMENT_SHADER,GetShaderiv,LinkProgram,ShaderSource,VERTEX_SHADER};
use gl::types::{GLchar,GLenum,GLint,GLuint};
use std::fs::read;
use std::ptr::{addr_of,null};

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

		let cmpshd = |nam: & str,typ:GLenum| -> GLuint {
			let typstr = match typ {
				FRAGMENT_SHADER => "fragment",
				VERTEX_SHADER   => "vertex",
				_               => panic!("invalid shader type {}",typ),
			};

			let filext = match typ {
				FRAGMENT_SHADER => "frag",
				VERTEX_SHADER   => "vert",
				_               => panic!("invalid shader type {}",typ),
			};

			let mut pth = String::new();
			pth.push_str(datpth());
			pth.push_str("/shader/");
			pth.push_str(nam);
			pth.push(    '.');
			pth.push_str(filext);
			pth.push_str(".glsl");

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

			let src = read(pth).expect("unable to read shader at");

			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 {panic!("unable to compile shader");}

				return shd;
			}
		};

		let frgshd = cmpshd("main",FRAGMENT_SHADER);
		let vtxshd = cmpshd("main",VERTEX_SHADER);
		
		unsafe {
			let prg = CreateProgram();
			AttachShader(prg,frgshd);
			AttachShader(prg,vtxshd);
			LinkProgram(prg);

			DeleteShader(frgshd);
			DeleteShader(vtxshd);

			return prg;
		}
	}
}