Trait glium::Surface

source ·
pub trait Surface {
Show 24 methods // Required methods fn clear( &mut self, rect: Option<&Rect>, color: Option<(f32, f32, f32, f32)>, color_srgb: bool, depth: Option<f32>, stencil: Option<i32> ); fn get_dimensions(&self) -> (u32, u32); fn get_depth_buffer_bits(&self) -> Option<u16>; fn get_stencil_buffer_bits(&self) -> Option<u16>; fn draw<'a, 'b, V, I, U>( &mut self, _: V, _: I, program: &Program, uniforms: &U, draw_parameters: &DrawParameters<'_> ) -> Result<(), DrawError> where V: MultiVerticesSource<'b>, I: Into<IndicesSource<'a>>, U: Uniforms; fn blit_from_frame( &self, source_rect: &Rect, target_rect: &BlitTarget, filter: MagnifySamplerFilter ); fn blit_from_simple_framebuffer( &self, source: &SimpleFrameBuffer<'_>, source_rect: &Rect, target_rect: &BlitTarget, filter: MagnifySamplerFilter ); fn blit_from_multioutput_framebuffer( &self, source: &MultiOutputFrameBuffer<'_>, source_rect: &Rect, target_rect: &BlitTarget, filter: MagnifySamplerFilter ); fn blit_color<S>( &self, source_rect: &Rect, target: &S, target_rect: &BlitTarget, filter: MagnifySamplerFilter ) where S: Surface; // Provided methods fn clear_color(&mut self, red: f32, green: f32, blue: f32, alpha: f32) { ... } fn clear_color_srgb(&mut self, red: f32, green: f32, blue: f32, alpha: f32) { ... } fn clear_depth(&mut self, value: f32) { ... } fn clear_stencil(&mut self, value: i32) { ... } fn clear_color_and_depth(&mut self, color: (f32, f32, f32, f32), depth: f32) { ... } fn clear_color_srgb_and_depth( &mut self, color: (f32, f32, f32, f32), depth: f32 ) { ... } fn clear_color_and_stencil( &mut self, color: (f32, f32, f32, f32), stencil: i32 ) { ... } fn clear_color_srgb_and_stencil( &mut self, color: (f32, f32, f32, f32), stencil: i32 ) { ... } fn clear_depth_and_stencil(&mut self, depth: f32, stencil: i32) { ... } fn clear_all( &mut self, color: (f32, f32, f32, f32), depth: f32, stencil: i32 ) { ... } fn clear_all_srgb( &mut self, color: (f32, f32, f32, f32), depth: f32, stencil: i32 ) { ... } fn has_depth_buffer(&self) -> bool { ... } fn has_stencil_buffer(&self) -> bool { ... } fn blit_whole_color_to<S>( &self, target: &S, target_rect: &BlitTarget, filter: MagnifySamplerFilter ) where S: Surface { ... } fn fill<S>(&self, target: &S, filter: MagnifySamplerFilter) where S: Surface { ... }
}
Expand description

Object that can be drawn upon.

What does the GPU do when you draw?

This is a summary of everything that happens when you call the draw function. Note that this is not necessarily exactly what happens. Backends are free to do whatever they want as long as it always matches the expected outcome.

Step 1: Vertex shader

For each vertex in the vertices source, the GPU invokes the vertex shader that is part of the program, and passes the corresponding vertex’s attributes to it.

The vertex shader must write the special gl_Position variable in order to indicate the four-dimensions coordinates of the vertex. In order to understand what these coordinates mean, see the “vertex post-processing” step below.

In addition to the position of the vertex, the vertex shader can also specify the values of various vertex attributes.

Step 2: Tessellation (optional)

Step 3: Geometry shader (optional)

If you specify a geometry shader, then the GPU will invoke it once for each primitive.

The geometry shader can output multiple primitives.

Step 4: Transform feedback (optional)

TODO: TODO: talk about transform_feedback_primitives_written_query as well

Step 5: Vertex post-processing

The vertex shader step told the GPU what the coordinates of each vertex are, but these coordinates have four dimensions, named x, y, z and w.

The GPU then computes the position of the vertex on the 2D surface you are drawing on, and the depth of this vertex:

window_x = viewport_left + viewport_width * ((x / w) + 1.0) / 2.0
window_y = viewport_bottom + viewport_height * ((y / w) + 1.0) / 2.0
depth = depth_near + (depth_far - depth_near) * ((z / w) + 1.0) / 2.0

viewport_left, viewport_width, viewport_bottom and viewport_height correspond to the viewport member of the draw parameters, and depth_near and depth_far correspond to the depth_range member.

This means that if x / w, y / w or z / w are equal to -1.0, then the result will be viewport_left, viewport_bottom or depth_near. If they are equal to 1.0, the result will be viewport_left + viewport_width (the right of the viewport), viewport_bottom + viewport_height (the top of the viewport) or depth_far.

For example if you want to draw a rectangle that covers the whole screen, it should be made of four vertices whose coordinates are (-1.0, -1.0, 0.0, 1.0) (bottom-left corner), (-1.0, 1.0, 0.0, 1.0) (top-left corner), (1.0, 1.0, 0.0, 1.0) (top-right corner) and (1.0, -1.0, 0.0, 1.0) (bottom-right corner).

Step 6: Primitive assembly

The next step consists in building the primitives. Triangle strips, triangle fans and line strips are turned into individual triangles or lines.

Triangle strips obey certain rules for the order of indices. For example the triangle strip 0, 1, 2, 3, 4, 5 does not correspond to 0, 1, 2, 1, 2, 3, 2, 3, 4, 3, 4, 5 as you would expect, but to 0, 1, 2, 1, 3, 2, 2, 3, 4, 3, 5, 4 (some indices are reversed). This is important with regards to the face culling step below.

Then, if you did specify PrimitiveMode, it is used. If you specified Line, triangles are turned into lines. If specified Point, triangles and lines are turned into points.

The GPU then looks at the screen coordinates of each primitive, and discards primitives that are entirely outside of the window.

Note that points whose centers are outside of the viewport are discarded, even if the point width would be big enough for the point to be visible. However this standard behavior is not respected by nVidia drivers, which show the points anyway.

If a query has been specified through primitives_generated_query, then its value is updated.

Step 7: Face culling (triangles only)

This step is purely an optimization step and only concerns triangles.

If you specify a value for backface_culling other than CullingDisabled, the GPU will discard triangles depending on the way that the vertices are arranged on the window. You can either discard triangles whose vertices are clockwise or counterclockwise.

For more information, see the BackfaceCullingMode documentation.

Step 8: Rasterization

Now that the GPU knows where on the window the various triangles, points or lines are, it will determine which pixels of the surface are part of each primitive.

For points and lines, this step depends on the points width and line width that you specified in the draw parameters. If you specify the smooth parameter, then the borders of the primitives will see their alpha value adjusted.

The attributes of each vertex that are marked as smooth (which is the default value) are being interpolated, and the GPU assigns a value for each attribute for each pixel.

Step 9: Fragment shader

The GPU now executes the fragment shader once for each pixel of each primitive. The vertex attributes that were interpolated at the previous step are passed to the fragment shader.

The fragment shader must return the color to write by setting the value of gl_FragColor.

If the target framebuffer has multisampling enabled, then each pixel of the target image is in turn split into four subpixels. The output of the fragment shader is copied and written into each subpixel. If multisampling in the draw parameters is true (its default value), only subpixels that belong to the triangle are written.

If a query has been specified through samples_passed_query, then its value is updated.

Step 10: Pixel ownership

This step is mostly an implementation detail. If the window you are drawing on is not on the foreground, or if it is partially obstructed, then the pixels that are not on the foreground will be discarded.

This is only relevant if you draw to the default framebuffer.

This step has to be taken into account in some situations. For example if you query the number of samples that have been written, the ones that don’t pass the pixel ownership test won’t count.

Step 11: Scissor test

If scissor has been specified, then all the pixels that are outside of this rect are discarded.

Step 12: Depth test

In addition to the colors, surfaces can also have a depth buffer attached to it. In this situation, just like each pixel has a color, each pixel of the surface also has an associated depth value.

If a depth buffer is present, the GPU will compare the depth value of the pixel currently being processed, with the existing depth value. Depending on the value of depth_test in the draw parameters, the depth test will either pass, in which case the pipeline continues, or fail, in which case the pixel is discarded. If the value of depth_write is true and the test passed, it will then also write the depth value of the pixel on the depth buffer.

The purpose of this test is to avoid drawing elements that are in the background of the scene over elements that are in the foreground.

See the documentation of DepthTest for more informations.

Step 13: Stencil test

Similar to the depth buffer, surfaces can also have a stencil buffer.

The stencil_test_clockwise and stencil_test_counter_clockwise draw parameters specify the operation to use to check whether or not each pixel passes the stencil test. Pixels that fail the stencil test won’t be drawn on the screen.

The *_clockwise members are relevant for polygons that are displayed clockwise, and the *_counter_clockwise members are relevant for polygons that are displayed counterclockwise. See also the face culling step for more infos. Lines and points always use the *_clockwise members.

There are three possibilities for each pixel: either it fails the stencil test, or it passes the stencil test but failed the depth test, or it passes both the stencil test and depth test. You can specify for each of these three situations what to do with the value in the stencil buffer with the draw parameters.

Step 14: Blending

For each pixel to write, the GPU takes the RGBA color that the fragment shader has returned and the existing RGBA color already written on the surface, and merges the two.

The way they are merged depends on the value of blending_function. This allows you to choose how alpha colors are merged together.

See the documentation of BlendingFunction fore more informations.

Step 15: Dithering (optional)

If dithering is true in the draw parameters, then a dithering algorithm is applied.

When you draw a gradient of colors, the boundary between each individual color value is visible. Thanks to an optical illusion, a dithering algorithm will change the color values of some pixels and hide the boundaries.

Step 16: Conversion to sRGB

If the target has sRGB enabled, then the output of the fragment will get some gamma correction.

Monitors don’t show colors linearly. For example a value of 0.5 isn’t shown half as bright as a value of 1.0. Instead the monitor will show colors as darker than they should be. In order to fix this problem, each pixel is modified to be made slightly brighter with the same factor as the monitor makes them darker.

Step 17: End

This is finally the step where colors are being written. The color_mask parameter allow you to specify whether each color component (red, green, blue and alpha) is written to the color buffer.

Required Methods§

source

fn clear( &mut self, rect: Option<&Rect>, color: Option<(f32, f32, f32, f32)>, color_srgb: bool, depth: Option<f32>, stencil: Option<i32> )

Clears some attachments of the target.

source

fn get_dimensions(&self) -> (u32, u32)

Returns the dimensions in pixels of the target.

source

fn get_depth_buffer_bits(&self) -> Option<u16>

Returns the number of bits of each pixel of the depth buffer.

Returns None if there is no depth buffer.

source

fn get_stencil_buffer_bits(&self) -> Option<u16>

Returns the number of bits of each pixel of the stencil buffer.

Returns None if there is no stencil buffer.

source

fn draw<'a, 'b, V, I, U>( &mut self, _: V, _: I, program: &Program, uniforms: &U, draw_parameters: &DrawParameters<'_> ) -> Result<(), DrawError>where V: MultiVerticesSource<'b>, I: Into<IndicesSource<'a>>, U: Uniforms,

Draws.

This is probably the most complex function of glium. Check out the rest of the documentation for example how to use it.

See above for what happens exactly on the GPU when you draw.

source

fn blit_from_frame( &self, source_rect: &Rect, target_rect: &BlitTarget, filter: MagnifySamplerFilter )

Blits from the default framebuffer.

source

fn blit_from_simple_framebuffer( &self, source: &SimpleFrameBuffer<'_>, source_rect: &Rect, target_rect: &BlitTarget, filter: MagnifySamplerFilter )

Blits from a simple framebuffer.

source

fn blit_from_multioutput_framebuffer( &self, source: &MultiOutputFrameBuffer<'_>, source_rect: &Rect, target_rect: &BlitTarget, filter: MagnifySamplerFilter )

Blits from a multi-output framebuffer.

source

fn blit_color<S>( &self, source_rect: &Rect, target: &S, target_rect: &BlitTarget, filter: MagnifySamplerFilter )where S: Surface,

Copies a rectangle of pixels from this surface to another surface.

The source_rect defines the area of the source (self) that will be copied, and the target_rect defines the area where the copied image will be pasted. If the source and target areas don’t have the same dimensions, the image will be resized to match. The filter parameter is relevant only in this situation.

It is possible for the source and the target to be the same surface. However if the rectangles overlap, then the behavior is undefined.

Note that there is no alpha blending, depth/stencil checking, etc. This function just copies pixels.

Provided Methods§

source

fn clear_color(&mut self, red: f32, green: f32, blue: f32, alpha: f32)

Clears the color attachment of the target.

source

fn clear_color_srgb(&mut self, red: f32, green: f32, blue: f32, alpha: f32)

Clears the color attachment of the target. The color is in sRGB format.

source

fn clear_depth(&mut self, value: f32)

Clears the depth attachment of the target.

source

fn clear_stencil(&mut self, value: i32)

Clears the stencil attachment of the target.

source

fn clear_color_and_depth(&mut self, color: (f32, f32, f32, f32), depth: f32)

Clears the color and depth attachments of the target.

source

fn clear_color_srgb_and_depth( &mut self, color: (f32, f32, f32, f32), depth: f32 )

Clears the color and depth attachments of the target. The color is in sRGB format.

source

fn clear_color_and_stencil(&mut self, color: (f32, f32, f32, f32), stencil: i32)

Clears the color and stencil attachments of the target.

source

fn clear_color_srgb_and_stencil( &mut self, color: (f32, f32, f32, f32), stencil: i32 )

Clears the color and stencil attachments of the target. The color is in sRGB format.

source

fn clear_depth_and_stencil(&mut self, depth: f32, stencil: i32)

Clears the depth and stencil attachments of the target.

source

fn clear_all(&mut self, color: (f32, f32, f32, f32), depth: f32, stencil: i32)

Clears the color, depth and stencil attachments of the target.

source

fn clear_all_srgb( &mut self, color: (f32, f32, f32, f32), depth: f32, stencil: i32 )

Clears the color, depth and stencil attachments of the target. The color is in sRGB format.

source

fn has_depth_buffer(&self) -> bool

Returns true if the surface has a depth buffer available.

source

fn has_stencil_buffer(&self) -> bool

Returns true if the surface has a stencil buffer available.

source

fn blit_whole_color_to<S>( &self, target: &S, target_rect: &BlitTarget, filter: MagnifySamplerFilter )where S: Surface,

Copies the entire surface to a target surface. See blit_color.

source

fn fill<S>(&self, target: &S, filter: MagnifySamplerFilter)where S: Surface,

Copies the entire surface to the entire target. See blit_color.

Implementors§