Struct Program

Source
pub struct Program { /* private fields */ }
Expand description

A combination of shaders linked together.

Implementations§

Source§

impl Program

Source

pub fn new<'a, F, I>( facade: &F, input: I, ) -> Result<Program, ProgramCreationError>
where I: Into<ProgramCreationInput<'a>>, F: Facade + ?Sized,

Builds a new program.

Source

pub fn from_source<'a, F>( facade: &F, vertex_shader: &'a str, fragment_shader: &'a str, geometry_shader: Option<&'a str>, ) -> Result<Program, ProgramCreationError>
where F: Facade + ?Sized,

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?
examples/simple.rs (lines 56-67)
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        (Exit,    Escape, GamepadInput::Start),
17        (Left,    ArrowLeft,  KeyA,  LeftStickLeft ),
18        (Right,   ArrowRight, KeyD,  LeftStickRight),
19        (Forward, ArrowUp,    KeyW,  LeftStickUp   ),
20        (Back,    ArrowDown,  KeyS,  LeftStickDown ),
21        (LookRight, MouseMoveRight, RightStickRight),
22        (LookLeft,  MouseMoveLeft,  RightStickLeft ),
23        (LookUp,    MouseMoveUp,    RightStickUp   ),
24        (LookDown,  MouseMoveDown,  RightStickDown )
25    )};
26
27    struct Graphics {
28        program: Program,
29        indices: IndexBuffer<u16>,
30        vertices: VertexBuffer<Vertex>,
31        normals: VertexBuffer<Normal>
32    }
33    let graphics: Rc<RefCell<Option<Graphics>>> = Rc::new(RefCell::new(None));
34    let graphics_setup = graphics.clone();
35    
36    let draw_parameters = DrawParameters {
37        backface_culling: draw_parameters::BackfaceCullingMode::CullClockwise,
38        ..params::alias_3d()
39    };
40
41    let mut pos = vec3(0.0, 0.0, -30.0);
42    let mut rot = vec2(0.0, 0.0);
43    let mut gravity = 0.0;
44
45    let mut frame_start = Instant::now();
46
47    thin_engine::builder(input).with_setup(|display, window, _| {
48        let _ = window.set_cursor_grab(CursorGrabMode::Confined);
49        let _ = window.set_cursor_grab(CursorGrabMode::Locked);
50        window.set_cursor_visible(false);
51        window.set_title("Walk Test");
52
53        let (indices, vertices, normals) = mesh!(
54            display, &teapot::INDICES, &teapot::VERTICES, &teapot::NORMALS
55        );
56        let program = Program::from_source(
57            display, shaders::VERTEX,
58            "#version 140
59            out vec4 colour;
60            in vec3 v_normal;
61            uniform vec3 light;
62            const vec3 albedo = vec3(0.1, 1.0, 0.3);
63            void main(){
64                float light_level = dot(light, v_normal);
65                colour = vec4(albedo * light_level, 1.0);
66            }", None,
67        ).unwrap();
68        graphics_setup.replace(Some(Graphics { program, indices, vertices, normals }));
69    }).with_update(|input, display, _, target, _| {
70        let graphics = graphics.borrow();
71        let Graphics { vertices, indices, normals, program } = graphics.as_ref().unwrap();
72        let delta_time = frame_start.elapsed().as_secs_f32();
73        frame_start = Instant::now();
74
75        let mut frame = display.draw();
76        let view = Mat4::view_matrix_3d(frame.get_dimensions(), 1.0, 1024.0, 0.1);
77
78        //handle gravity and jump
79        gravity += delta_time * 9.5;
80        if input.pressed(Jump) { gravity = -10.0 }
81
82        //set camera rotation
83        let look_move = input.dir(LookLeft, LookRight, LookUp, LookDown);
84        rot += look_move.scale(delta_time * 20.0);
85        rot.y = rot.y.clamp(-PI / 2.0, PI / 2.0);
86        let rx = Quat::from_y_rot(rot.x);
87        let ry = Quat::from_x_rot(rot.y);
88        let rot = rx * ry;
89
90        //move player based on view and gravity
91        let dir = input.dir_max_len_1(Right, Left, Forward, Back);
92        let move_dir = vec3(dir.x, 0.0, dir.y).scale(5.0*delta_time);
93        pos += move_dir.transform(&Mat3::from_rot(rx));
94        pos.y = (pos.y - gravity * delta_time).max(0.0);
95
96        if input.pressed(Exit) { target.exit() }
97
98        frame.clear_color_and_depth((0.0, 0.0, 0.0, 1.0), 1.0);
99        //draw teapot
100        frame.draw(
101            (vertices, normals), indices,
102            program, &uniform! {
103                view: view,
104                model: Mat4::from_scale(Vec3::splat(0.1)),
105                camera: Mat4::from_inverse_transform(pos, Vec3::ONE, rot),
106                light: vec3(1.0, -0.9, -1.0).normalise()
107            },
108            &draw_parameters,
109        ).unwrap();
110
111        frame.finish().unwrap();
112    }).build(event_loop).unwrap();
113}
More examples
Hide additional examples
examples/simple-fxaa.rs (lines 71-88)
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        );
67        let (teapot_indices, teapot_vertices, teapot_uvs, teapot_normals) = mesh!(
68            display, &teapot::INDICES, &teapot::VERTICES, &[] as &[TextureCoords; 0], &teapot::NORMALS
69        );
70
71        let program = Program::from_source(
72            display, shaders::VERTEX,
73            "#version 140
74            out vec4 colour;
75            in vec3 v_normal;
76            uniform vec3 light;
77            uniform mat4 camera;
78            uniform vec3 ambient;
79            uniform vec3 albedo;
80            uniform float shine;
81            void main() {
82                vec3 camera_dir = inverse(mat3(camera)) * vec3(0, 0, -1);
83                vec3 half_dir = normalize(camera_dir + light);
84                float specular = pow(max(dot(half_dir, v_normal), 0.0), shine);
85                float light_level = max(dot(light, v_normal), 0.0);
86                colour = vec4(albedo * light_level + ambient + vec3(specular), 1.0);
87            }", None
88        ).unwrap();
89        let fxaa = shaders::fxaa_shader(display).unwrap();
90        let normal = Program::from_source(
91            display, shaders::SCREEN_VERTEX, 
92            "#version 140
93            in vec2 uv;
94            uniform sampler2D tex;
95            out vec4 colour;
96            void main() {
97                colour = texture(tex, uv);
98            }", None
99        ).unwrap();
100        graphics_setup.replace(Some(Graphics {
101            screen_indices, screen_vertices, screen_uvs,
102            teapot_indices, teapot_vertices, teapot_uvs, teapot_normals,
103            program, normal, fxaa
104        }));
105    }).with_update(|input, display, _, _, _| {
106        let graphics = graphics.borrow();
107        let Graphics {
108            screen_indices, screen_vertices, screen_uvs,
109            teapot_indices, teapot_vertices, teapot_uvs, teapot_normals,
110            program, normal, fxaa
111        } = graphics.as_ref().unwrap();
112        let teapot_mesh = (teapot_vertices, teapot_normals, teapot_uvs);
113        let screen_mesh = (screen_vertices, screen_uvs);
114
115        let delta_time = frame_start.elapsed().as_secs_f32();
116        frame_start = Instant::now();
117
118        // using a small resolution to better show the effect of fxaa.
119        let size = (380, 216);
120        display.resize(size);
121        depth.resize_to_display(&display);
122        colour.resize_to_display(&display);
123
124        // press f to toggle FXAA
125        if input.pressed(FXAA) { fxaa_on = !fxaa_on }
126
127        let colour = colour.texture();
128        let depth = depth.texture();
129        let mut frame = SimpleFrameBuffer::with_depth_buffer(
130            display, colour, depth
131        ).unwrap();
132
133        let view = Mat4::view_matrix_3d(size, 1.0, 1024.0, 0.1);
134
135        // set camera rotation
136        let look_move = input.dir(LookLeft, LookRight, LookUp, LookDown);
137        rot += look_move.scale(delta_time * 20.0);
138        rot.y = rot.y.clamp(-PI / 2.0, PI / 2.0);
139        let rx = Quat::from_y_rot(rot.x);
140        let ry = Quat::from_x_rot(rot.y);
141        let rot = rx * ry;
142
143        // move player based on view
144        let dir = input.dir_max_len_1(Right, Left, Forward, Back);
145        let move_dir = vec3(dir.x, 0.0, dir.y).scale(5.0*delta_time);
146        pos += move_dir.transform(&Mat3::from_rot(rx));
147
148        frame.clear_color_and_depth((0.0, 0.0, 0.0, 1.0), 1.0);
149        // draw teapot
150        frame.draw(
151            teapot_mesh, teapot_indices,
152            program, &uniform! {
153                view: view,
154                model: Mat4::from_scale(Vec3::splat(0.1)),
155                camera: Mat4::from_inverse_transform(pos, Vec3::ONE, rot),
156                light:   vec3(0.1, 0.25, -1.0).normalise(),
157                albedo:  vec3(0.5, 0.1,   0.4),
158                ambient: vec3(0.0, 0.05,  0.1),
159                shine: 50.0f32,
160            },
161            &draw_parameters,
162        ).unwrap();
163
164        let mut frame = display.draw();
165        frame.draw(
166            screen_mesh, screen_indices, if fxaa_on { fxaa } else { normal },
167            &shaders::fxaa_uniforms(colour), &DrawParameters::default()
168        ).unwrap();
169        frame.finish().unwrap();
170    }).build(event_loop).unwrap();
171}
Source

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.

Source

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;
Source

pub fn get_uniform(&self, name: &str) -> Option<&Uniform>

Returns informations about a uniform variable, if it exists.

Source

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);
}
Source

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);
}
Source

pub fn get_transform_feedback_buffers(&self) -> &[TransformFeedbackBuffer]

Returns the list of transform feedback varyings.

Source

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.

Source

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.

Source

pub fn has_tessellation_shaders(&self) -> bool

Returns true if the program contains a tessellation stage.

Source

pub fn has_tessellation_control_shader(&self) -> bool

Returns true if the program contains a tessellation control stage.

Source

pub fn has_tessellation_evaluation_shader(&self) -> bool

Returns true if the program contains a tessellation evaluation stage.

Source

pub fn has_geometry_shader(&self) -> bool

Returns true if the program contains a geometry shader.

Source

pub fn get_attribute(&self, name: &str) -> Option<&Attribute>

Returns informations about an attribute, if it exists.

Source

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);
}
Source

pub fn has_srgb_output(&self) -> bool

Returns true if the program has been configured to output sRGB instead of RGB.

Source

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);
}
Source

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);
}
Source

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);
}
Source

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§

Source§

impl Debug for Program

Source§

fn fmt(&self, formatter: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl GlObject for Program

Source§

type Id = Handle

The type of identifier for this object.
Source§

fn get_id(&self) -> Handle

Returns the id of the object.

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> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert 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>

Convert 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)

Convert &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)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more