opengl_graphics/
shader_uniforms.rs1use gl;
5use gl::types::{GLboolean, GLint};
6use std::ffi::CString;
7use std::marker::PhantomData;
8
9use crate::back_end::GlGraphics;
11
12#[derive(Clone, Copy)]
14pub struct ShaderUniform<T: ?Sized> {
15 location: GLint,
16 phantom: PhantomData<T>,
17}
18
19pub trait UniformType {}
23
24#[derive(Clone, Copy)]
26pub struct SUFloat {}
27impl UniformType for SUFloat {}
28
29#[derive(Clone, Copy)]
31pub struct SUInt {}
32impl UniformType for SUInt {}
33
34#[derive(Clone, Copy)]
37pub struct SUVec2 {}
38impl UniformType for SUVec2 {}
39
40#[derive(Clone, Copy)]
43pub struct SUVec3 {}
44impl UniformType for SUVec3 {}
45
46#[derive(Clone, Copy)]
49pub struct SUVec4 {}
50impl UniformType for SUVec4 {}
51
52#[derive(Clone, Copy)]
55pub struct SUMat2x2 {}
56impl UniformType for SUMat2x2 {}
57
58#[derive(Clone, Copy)]
61pub struct SUMat3x3 {}
62impl UniformType for SUMat3x3 {}
63
64#[derive(Clone, Copy)]
67pub struct SUMat4x4 {}
68impl UniformType for SUMat4x4 {}
69
70impl GlGraphics {
71 pub fn get_uniform<T: UniformType + ?Sized>(&self, name: &str) -> Option<ShaderUniform<T>> {
73 self.get_current_program().and_then(|p| unsafe {
74 let c_source = CString::new(name).ok();
75 c_source.and_then(|name| {
76 let uniform = match gl::GetUniformLocation(p, name.as_ptr()) {
77 -1 => None,
78 location => Some(ShaderUniform {
79 location,
80 phantom: PhantomData,
81 }),
82 };
83 drop(name);
84 uniform
85 })
86 })
87 }
88}
89
90impl ShaderUniform<SUFloat> {
91 pub fn set(&self, gl: &GlGraphics, value: f32) {
93 if let Some(p) = gl.get_current_program() {
94 unsafe { gl::ProgramUniform1f(p, self.location, value) };
95 }
96 }
97}
98
99impl ShaderUniform<SUInt> {
100 pub fn set(&self, gl: &GlGraphics, value: i32) {
102 if let Some(p) = gl.get_current_program() {
103 unsafe { gl::ProgramUniform1i(p, self.location, value) };
104 }
105 }
106}
107
108impl ShaderUniform<SUVec2> {
109 pub fn set(&self, gl: &GlGraphics, value: &[f32; 2]) {
111 if let Some(p) = gl.get_current_program() {
112 unsafe { gl::ProgramUniform2f(p, self.location, value[0], value[1]) };
113 }
114 }
115}
116
117impl ShaderUniform<SUVec3> {
118 pub fn set(&self, gl: &GlGraphics, value: &[f32; 3]) {
120 if let Some(p) = gl.get_current_program() {
121 unsafe { gl::ProgramUniform3f(p, self.location, value[0], value[1], value[2]) }
122 }
123 }
124}
125
126impl ShaderUniform<SUVec4> {
127 pub fn set(&self, gl: &GlGraphics, value: &[f32; 4]) {
129 if let Some(p) = gl.get_current_program() {
130 unsafe {
131 gl::ProgramUniform4f(p, self.location, value[0], value[1], value[2], value[3])
132 }
133 }
134 }
135}
136
137impl ShaderUniform<SUMat2x2> {
138 pub fn set(&self, gl: &GlGraphics, values: &[f32; 4]) {
140 if let Some(p) = gl.get_current_program() {
141 unsafe {
142 gl::ProgramUniformMatrix2fv(
143 p,
144 self.location,
145 1 as GLint,
146 false as GLboolean,
147 values.as_ptr(),
148 )
149 }
150 }
151 }
152}
153
154impl ShaderUniform<SUMat3x3> {
155 pub fn set(&self, gl: &GlGraphics, values: &[f32; 9]) {
157 if let Some(p) = gl.get_current_program() {
158 unsafe {
159 gl::ProgramUniformMatrix3fv(
160 p,
161 self.location,
162 1 as GLint,
163 false as GLboolean,
164 values.as_ptr(),
165 )
166 }
167 }
168 }
169}
170
171impl ShaderUniform<SUMat4x4> {
172 pub fn set(&self, gl: &GlGraphics, values: &[f32; 16]) {
174 if let Some(p) = gl.get_current_program() {
175 unsafe {
176 gl::ProgramUniformMatrix4fv(
177 p,
178 self.location,
179 1 as GLint,
180 false as GLboolean,
181 values.as_ptr(),
182 )
183 }
184 }
185 }
186}