pub struct Program { /* private fields */ }
Expand description
A combination of shaders linked together.
Implementations§
Source§impl Program
impl Program
Sourcepub fn new<'a, F, I>(
facade: &F,
input: I,
) -> Result<Program, ProgramCreationError>
pub fn new<'a, F, I>( facade: &F, input: I, ) -> Result<Program, ProgramCreationError>
Builds a new program.
Sourcepub fn from_source<'a, F>(
facade: &F,
vertex_shader: &'a str,
fragment_shader: &'a str,
geometry_shader: Option<&'a str>,
) -> Result<Program, ProgramCreationError>
pub fn from_source<'a, F>( facade: &F, vertex_shader: &'a str, fragment_shader: &'a str, geometry_shader: Option<&'a str>, ) -> Result<Program, ProgramCreationError>
Builds a new program from GLSL source code.
A program is a group of shaders linked together.
§Parameters
vertex_shader
: Source code of the vertex shader.fragment_shader
: Source code of the fragment shader.geometry_shader
: Source code of the geometry shader.
§Example
let program = glium::Program::from_source(&display, vertex_source, fragment_source,
Some(geometry_source));
Examples found in repository?
9fn main() {
10 use Action::*;
11 let event_loop = EventLoop::new().unwrap();
12 event_loop.set_control_flow(ControlFlow::Poll);
13
14 let input = { use base_input_codes::*; input_map!(
15 (Jump, Space, GamepadInput::South),
16 // square brackets mean that all input codes must be pressed for the bind to be pressed
17 (Exit, [ControlLeft, Escape], GamepadInput::Start),
18 (Left, ArrowLeft, KeyA, LeftStickLeft ),
19 (Right, ArrowRight, KeyD, LeftStickRight),
20 (Forward, ArrowUp, KeyW, LeftStickUp ),
21 (Back, ArrowDown, KeyS, LeftStickDown ),
22 (LookRight, MouseMoveRight, RightStickRight),
23 (LookLeft, MouseMoveLeft, RightStickLeft ),
24 (LookUp, MouseMoveUp, RightStickUp ),
25 (LookDown, MouseMoveDown, RightStickDown )
26 )};
27
28 struct Graphics {
29 program: Program,
30 indices: IndexBuffer<u16>,
31 vertices: VertexBuffer<Vertex>,
32 normals: VertexBuffer<Normal>
33 }
34 let graphics: Rc<RefCell<Option<Graphics>>> = Rc::new(RefCell::new(None));
35 let graphics_setup = graphics.clone();
36
37 let draw_parameters = DrawParameters {
38 backface_culling: draw_parameters::BackfaceCullingMode::CullClockwise,
39 ..params::alias_3d()
40 };
41
42 let mut pos = vec3(0.0, 0.0, -30.0);
43 let mut rot = vec2(0.0, 0.0);
44 let mut gravity = 0.0;
45
46 let mut frame_start = Instant::now();
47
48 thin_engine::builder(input).with_setup(|display, window, _| {
49 let _ = window.set_cursor_grab(CursorGrabMode::Confined);
50 let _ = window.set_cursor_grab(CursorGrabMode::Locked);
51 window.set_cursor_visible(false);
52 window.set_title("Walk Test");
53
54 let (indices, vertices, normals) = mesh!(
55 display, &teapot::INDICES, &teapot::VERTICES, &teapot::NORMALS
56 ).unwrap();
57 let program = Program::from_source(
58 display,
59 "#version 140
60 in vec3 position;
61 in vec3 normal;
62 out vec3 v_normal;
63
64 uniform mat4 camera;
65 uniform mat4 model;
66 uniform mat4 perspective;
67
68 void main() {
69 mat3 norm_mat = transpose(inverse(mat3(camera * model)));
70 v_normal = normalize(norm_mat * normal);
71 gl_Position = perspective * camera * model * vec4(position, 1);
72 }",
73 "#version 140
74 out vec4 colour;
75 in vec3 v_normal;
76
77 uniform vec3 light;
78 const vec3 albedo = vec3(0.1, 1.0, 0.3);
79
80 void main(){
81 float light_level = dot(light, v_normal);
82 colour = vec4(albedo * light_level, 1.0);
83 }", None,
84 ).unwrap();
85 graphics_setup.replace(Some(Graphics { program, indices, vertices, normals }));
86 }).with_update(|input, display, _, target, _| {
87 let graphics = graphics.borrow();
88 let Graphics { vertices, indices, normals, program } = graphics.as_ref().unwrap();
89 let delta_time = frame_start.elapsed().as_secs_f32();
90 frame_start = Instant::now();
91
92 let mut frame = display.draw();
93 let perspective = Mat4::perspective_3d(frame.get_dimensions(), 1.0, 1024.0, 0.1);
94
95 // handle gravity and jump
96 gravity += delta_time * 9.5;
97 if input.pressed(Jump) { gravity = -10.0 }
98
99 // set camera rotation
100 let look_move = input.dir(LookRight, LookLeft, LookUp, LookDown);
101 rot += look_move.scale(delta_time * 15.0);
102 rot.y = rot.y.clamp(-PI / 2.0, PI / 2.0);
103 let rx = Quat::from_y_rot(rot.x);
104 let ry = Quat::from_x_rot(-rot.y);
105 let rot = rx * ry;
106
107 // move player based on camera and gravity
108 let dir = input.dir_max_len_1(Right, Left, Forward, Back);
109 let move_dir = vec3(dir.x, 0.0, dir.y).scale(5.0*delta_time);
110 pos += Mat3::from_rot(rx) * move_dir;
111 pos.y = (pos.y - gravity * delta_time).max(0.0);
112
113 if input.pressed(Exit) { target.exit() }
114
115 frame.clear_color_and_depth((0.0, 0.0, 0.0, 1.0), 1.0);
116 //draw teapot
117 frame.draw(
118 (vertices, normals), indices,
119 program, &uniform! {
120 perspective: perspective,
121 model: Mat4::from_scale(Vec3::splat(0.1)),
122 camera: Mat4::from_inverse_transform(pos, Vec3::ONE, rot),
123 light: vec3(1.0, -0.9, -1.0).normalise()
124 },
125 &draw_parameters,
126 ).unwrap();
127
128 frame.finish().unwrap();
129 }).build(event_loop).unwrap();
130}
More examples
13fn main() {
14 use Action::*;
15 let event_loop = EventLoop::new().unwrap();
16 event_loop.set_control_flow(ControlFlow::Poll);
17
18 let mut colour = ResizableTexture2d::default();
19 let mut depth = ResizableDepthTexture2d::default();
20
21 let input = { use base_input_codes::*; input_map!(
22 (Left, ArrowLeft, KeyA, LeftStickLeft ),
23 (Right, ArrowRight, KeyD, LeftStickRight),
24 (Forward, ArrowUp, KeyW, LeftStickUp ),
25 (Back, ArrowDown, KeyS, LeftStickDown ),
26 (LookRight, MouseMoveRight, RightStickRight),
27 (LookLeft, MouseMoveLeft, RightStickLeft ),
28 (LookUp, MouseMoveUp, RightStickUp ),
29 (LookDown, MouseMoveDown, RightStickDown ),
30 (FXAA, KeyF, GamepadInput::North)
31 ) };
32 struct Graphics {
33 screen_indices: IndexBuffer<u32>,
34 screen_vertices: VertexBuffer<Vertex>,
35 screen_uvs: VertexBuffer<TextureCoords>,
36
37 teapot_indices: IndexBuffer<u16>,
38 teapot_vertices: VertexBuffer<Vertex>,
39 teapot_uvs: VertexBuffer<TextureCoords>,
40 teapot_normals: VertexBuffer<Normal>,
41
42 fxaa: Program, normal: Program, program: Program
43 }
44 let graphics: Rc<RefCell<Option<Graphics>>> = Rc::default();
45 let graphics_setup = graphics.clone();
46
47 let draw_parameters = DrawParameters {
48 backface_culling: draw_parameters::BackfaceCullingMode::CullClockwise,
49 ..params::alias_3d()
50 };
51 let mut fxaa_on = true;
52
53 let mut pos = vec3(0.0, 0.0, -30.0);
54 let mut rot = vec2(0.0, 0.0);
55
56 let mut frame_start = Instant::now();
57
58 thin_engine::builder(input).with_setup(|display, window, _| {
59 window.set_title("FXAA Test");
60 let _ = window.set_cursor_grab(CursorGrabMode::Confined);
61 let _ = window.set_cursor_grab(CursorGrabMode::Locked);
62 window.set_cursor_visible(false);
63
64 let (screen_indices, screen_vertices, screen_uvs) = mesh!(
65 display, &screen::INDICES, &screen::VERTICES, &screen::UVS
66 ).unwrap();
67 let (teapot_indices, teapot_vertices, teapot_uvs, teapot_normals) = mesh!(
68 display, &teapot::INDICES, &teapot::VERTICES, &[] as &[TextureCoords; 0], &teapot::NORMALS
69 ).unwrap();
70
71 let program = Program::from_source(
72 display,
73 "#version 140
74 in vec3 position;
75 in vec3 normal;
76
77 out vec3 v_normal;
78
79 uniform mat4 model;
80 uniform mat4 perspective;
81 uniform mat4 camera;
82
83 void main() {
84 mat3 norm_mat = transpose(inverse(mat3(camera * model)));
85 v_normal = normalize(norm_mat * normal);
86 gl_Position = perspective * camera * model * vec4(position, 1);
87 }",
88 "#version 140
89 out vec4 colour;
90 in vec3 v_normal;
91 uniform vec3 light;
92 uniform mat4 camera;
93 uniform vec3 ambient;
94 uniform vec3 albedo;
95 uniform float shine;
96 void main() {
97 vec3 camera_dir = inverse(mat3(camera)) * vec3(0, 0, -1);
98 vec3 half_dir = normalize(camera_dir + light);
99 float specular = pow(max(dot(half_dir, v_normal), 0.0), shine);
100 float light_level = max(dot(light, v_normal), 0.0);
101 colour = vec4(albedo * light_level + ambient + vec3(specular), 1.0);
102 }", None
103 ).unwrap();
104 let fxaa = shaders::fxaa_shader(display).unwrap();
105 let normal = Program::from_source(
106 display,
107 "#version 140
108 in vec2 texture_coords;
109 out vec2 uv;
110 in vec3 position;
111 void main() {
112 uv = texture_coords;
113 gl_Position = vec4(position, 1);
114 }",
115 "#version 140
116 in vec2 uv;
117 uniform sampler2D tex;
118 out vec4 colour;
119 void main() {
120 colour = texture(tex, uv);
121 }", None
122 ).unwrap();
123 graphics_setup.replace(Some(Graphics {
124 screen_indices, screen_vertices, screen_uvs,
125 teapot_indices, teapot_vertices, teapot_uvs, teapot_normals,
126 program, normal, fxaa
127 }));
128 }).with_update(|input, display, _, _, _| {
129 let graphics = graphics.borrow();
130 let Graphics {
131 screen_indices, screen_vertices, screen_uvs,
132 teapot_indices, teapot_vertices, teapot_uvs, teapot_normals,
133 program, normal, fxaa
134 } = graphics.as_ref().unwrap();
135 let teapot_mesh = (teapot_vertices, teapot_normals, teapot_uvs);
136 let screen_mesh = (screen_vertices, screen_uvs);
137
138 let delta_time = frame_start.elapsed().as_secs_f32();
139 frame_start = Instant::now();
140
141 // using a small resolution to better show the effect of fxaa.
142 let size = (380, 216);
143 display.resize(size);
144 depth.resize_to_display(&display);
145 colour.resize_to_display(&display);
146
147 // press f or gamepad north to toggle FXAA
148 if input.pressed(FXAA) { fxaa_on = !fxaa_on }
149
150 let colour = colour.texture();
151 let depth = depth.texture();
152 let mut frame = SimpleFrameBuffer::with_depth_buffer(
153 display, colour, depth
154 ).unwrap();
155
156 let perspective = Mat4::perspective_3d(size, 1.0, 1024.0, 0.1);
157
158 // set camera rotation
159 let look_move = input.dir(LookRight, LookLeft, LookUp, LookDown);
160 rot += look_move.scale(delta_time * 15.0);
161 rot.y = rot.y.clamp(-PI / 2.0, PI / 2.0);
162 let rx = Quat::from_y_rot(rot.x);
163 let ry = Quat::from_x_rot(-rot.y);
164 let rot = rx * ry;
165
166 // move player based on camera
167 let dir = input.dir_max_len_1(Right, Left, Forward, Back);
168 let move_dir = vec3(dir.x, 0.0, dir.y).scale(5.0*delta_time);
169 pos += Mat3::from_rot(rx) * move_dir;
170
171 frame.clear_color_and_depth((0.0, 0.0, 0.0, 1.0), 1.0);
172 // draw teapot
173 frame.draw(
174 teapot_mesh, teapot_indices,
175 program, &uniform! {
176 perspective: perspective,
177 model: Mat4::from_scale(Vec3::splat(0.1)),
178 camera: Mat4::from_inverse_transform(pos, Vec3::ONE, rot),
179 light: vec3(0.1, 0.25, -1.0).normalise(),
180 albedo: vec3(0.5, 0.1, 0.4),
181 ambient: vec3(0.0, 0.05, 0.1),
182 shine: 50.0f32,
183 },
184 &draw_parameters,
185 ).unwrap();
186
187 let mut frame = display.draw();
188 frame.draw(
189 screen_mesh, screen_indices, if fxaa_on { fxaa } else { normal },
190 &shaders::fxaa_uniforms(colour), &DrawParameters::default()
191 ).unwrap();
192 frame.finish().unwrap();
193 }).build(event_loop).unwrap();
194}
Sourcepub fn get_binary(&self) -> Result<Binary, GetBinaryError>
pub fn get_binary(&self) -> Result<Binary, GetBinaryError>
Returns the program’s compiled binary.
You can store the result in a file, then reload it later. This avoids having to compile the source code every time.
Sourcepub fn get_frag_data_location(&self, name: &str) -> Option<u32>
pub fn get_frag_data_location(&self, name: &str) -> Option<u32>
Returns the location of an output fragment, if it exists.
The location is low-level information that is used internally by glium. You probably don’t need to call this function.
You can declare output fragments in your shaders by writing:
out vec4 foo;
Sourcepub fn get_uniform(&self, name: &str) -> Option<&Uniform>
pub fn get_uniform(&self, name: &str) -> Option<&Uniform>
Returns informations about a uniform variable, if it exists.
Sourcepub fn uniforms(&self) -> Iter<'_, String, Uniform>
pub fn uniforms(&self) -> Iter<'_, String, Uniform>
Returns an iterator to the list of uniforms.
§Example
for (name, uniform) in program.uniforms() {
println!("Name: {} - Type: {:?}", name, uniform.ty);
}
Sourcepub fn get_uniform_blocks(
&self,
) -> &HashMap<String, UniformBlock, BuildHasherDefault<FnvHasher>>
pub fn get_uniform_blocks( &self, ) -> &HashMap<String, UniformBlock, BuildHasherDefault<FnvHasher>>
Returns a list of uniform blocks.
§Example
for (name, uniform) in program.get_uniform_blocks() {
println!("Name: {}", name);
}
Sourcepub fn get_transform_feedback_buffers(&self) -> &[TransformFeedbackBuffer]
pub fn get_transform_feedback_buffers(&self) -> &[TransformFeedbackBuffer]
Returns the list of transform feedback varyings.
Sourcepub fn transform_feedback_matches(
&self,
format: &&'static [(Cow<'static, str>, usize, i32, AttributeType, bool)],
stride: usize,
) -> bool
pub fn transform_feedback_matches( &self, format: &&'static [(Cow<'static, str>, usize, i32, AttributeType, bool)], stride: usize, ) -> bool
True if the transform feedback output of this program matches the specified VertexFormat
and stride
.
The stride
is the number of bytes between two vertices.
Sourcepub fn get_output_primitives(&self) -> Option<OutputPrimitives>
pub fn get_output_primitives(&self) -> Option<OutputPrimitives>
Returns the type of geometry that transform feedback would generate, or None
if it
depends on the vertex/index data passed when drawing.
This corresponds to GL_GEOMETRY_OUTPUT_TYPE
or GL_TESS_GEN_MODE
. If the program doesn’t
contain either a geometry shader or a tessellation evaluation shader, returns None
.
Sourcepub fn has_tessellation_shaders(&self) -> bool
pub fn has_tessellation_shaders(&self) -> bool
Returns true if the program contains a tessellation stage.
Sourcepub fn has_tessellation_control_shader(&self) -> bool
pub fn has_tessellation_control_shader(&self) -> bool
Returns true if the program contains a tessellation control stage.
Sourcepub fn has_tessellation_evaluation_shader(&self) -> bool
pub fn has_tessellation_evaluation_shader(&self) -> bool
Returns true if the program contains a tessellation evaluation stage.
Sourcepub fn has_geometry_shader(&self) -> bool
pub fn has_geometry_shader(&self) -> bool
Returns true if the program contains a geometry shader.
Sourcepub fn get_attribute(&self, name: &str) -> Option<&Attribute>
pub fn get_attribute(&self, name: &str) -> Option<&Attribute>
Returns informations about an attribute, if it exists.
Sourcepub fn attributes(&self) -> Iter<'_, String, Attribute>
pub fn attributes(&self) -> Iter<'_, String, Attribute>
Returns an iterator to the list of attributes.
§Example
for (name, attribute) in program.attributes() {
println!("Name: {} - Type: {:?}", name, attribute.ty);
}
Sourcepub fn has_srgb_output(&self) -> bool
pub fn has_srgb_output(&self) -> bool
Returns true if the program has been configured to output sRGB instead of RGB.
Sourcepub fn get_shader_storage_blocks(
&self,
) -> &HashMap<String, UniformBlock, BuildHasherDefault<FnvHasher>>
pub fn get_shader_storage_blocks( &self, ) -> &HashMap<String, UniformBlock, BuildHasherDefault<FnvHasher>>
Returns the list of shader storage blocks.
§Example
for (name, uniform) in program.get_shader_storage_blocks() {
println!("Name: {}", name);
}
Sourcepub fn get_atomic_counters(
&self,
) -> &HashMap<String, UniformBlock, BuildHasherDefault<FnvHasher>>
pub fn get_atomic_counters( &self, ) -> &HashMap<String, UniformBlock, BuildHasherDefault<FnvHasher>>
Returns the list of shader storage blocks.
§Example
for (name, uniform) in program.get_atomic_counters() {
println!("Name: {}", name);
}
Sourcepub fn get_subroutine_uniforms(
&self,
) -> &HashMap<(String, ShaderStage), SubroutineUniform, BuildHasherDefault<FnvHasher>>
pub fn get_subroutine_uniforms( &self, ) -> &HashMap<(String, ShaderStage), SubroutineUniform, BuildHasherDefault<FnvHasher>>
Returns the subroutine uniforms of this program.
Since subroutine uniforms are unique per shader and not per program,
the keys of the HashMap
are in the format ("subroutine_name", ShaderStage)
.
§Example
for (&(ref name, shader), uniform) in program.get_subroutine_uniforms() {
println!("Name: {}", name);
}
Sourcepub fn uses_point_size(&self) -> bool
pub fn uses_point_size(&self) -> bool
Returns true if the program has been configured to use the gl_PointSize
variable.
If the program uses gl_PointSize
without having been configured appropriately, then
setting the value of gl_PointSize
will have no effect.
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for Program
impl !RefUnwindSafe for Program
impl !Send for Program
impl !Sync for Program
impl Unpin for Program
impl !UnwindSafe for Program
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait>
(where Trait: Downcast
) to Box<dyn Any>
. Box<dyn Any>
can
then be further downcast
into Box<ConcreteType>
where ConcreteType
implements Trait
.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait>
(where Trait: Downcast
) to Rc<Any>
. Rc<Any>
can then be
further downcast
into Rc<ConcreteType>
where ConcreteType
implements Trait
.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &Any
’s vtable from &Trait
’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &mut Any
’s vtable from &mut Trait
’s.