glium/lib.rs
1/*!
2Easy-to-use, high-level, OpenGL3+ wrapper.
3
4Glium is based on glutin - a cross-platform crate for building an OpenGL window and handling
5application events.
6
7Glium provides a [`Display`] which uses `glutin` for the Window and its associated GL Context.
8
9# Initialization
10
11The initialisation of a simple glium display occurs in two steps.
12
13```no_run
14extern crate glium;
15// Use the re-exported winit dependency to avoid version mismatches.
16// Requires the `simple_window_builder` feature.
17use glium::winit;
18
19fn main() {
20 // 1. The **winit::EventLoop** for handling events.
21 let event_loop = winit::event_loop::EventLoopBuilder::new().build().unwrap();
22 // 2. Create a glutin context and glium Display
23 let (window, display) = glium::backend::glutin::SimpleWindowBuilder::new().build(&event_loop);
24}
25```
26
27The `display` object is the most important object of this library and is used when you build
28buffers, textures, etc. and when you draw.
29
30You can clone it and pass it around. However it doesn't implement the `Send` and `Sync` traits,
31meaning that you can't pass it to another thread.
32
33The display has ownership of both the window and context, and also provides some methods related to
34domains such as events handling.
35
36# Overview
37
38OpenGL is similar to drawing software: you draw something, then draw over it, then over it
39again, etc. until you are satisfied of the result.
40
41Once you have a `display`, you can call `let mut frame = display.draw();` to start drawing. This
42`frame` object implements [the `Surface` trait](`Surface`) and provides some functions
43such as `clear_color`, but also allows you to draw with the rendering pipeline.
44
45In order to draw something, you will need to pass:
46
47 - A source of vertices (see the [`vertex`](`vertex`) module)
48 - A source of indices (see the [`index`](`index`) module)
49 - A program that contains the shader that the GPU will execute (see the
50 [`program`](`mod@program`) module)
51 - A list of uniforms for the program (see the [`uniforms`](`uniforms`) module)
52 - Draw parameters to customize the drawing process (see the
53 [`draw_parameters`](`draw_parameters`) module)
54
55Once you have finished drawing, you can call `frame.finish()` to swap buffers and present the
56result to the user.
57
58# OpenGL equivalents in glium
59
60 - **Bind points**: Glium automatically binds and unbinds buffers, textures, etc. in an optimized
61 way.
62 - **Buffers**: Buffers are strongly typed and can be used through `vertex::VertexBuffer`,
63 `index::IndexBuffer` or `uniforms::UniformBuffer`.
64 - **Debug output**: If you compile in debug mode, glium registers a debug output callback and
65 panics if an OpenGL error happens.
66 - **Framebuffer Objects**: FBOs are automatically managed by glium and are stored in the `Context`
67 object. You can specify the attachments that you wish with the `framebuffer` module.
68 - **Instancing**: Instancing is done either by passing a `vertex::EmptyInstanceAttributes` marker
69 or one or several references to vertex buffers wrapped inside a `PerInstance` struct. See the
70 `vertex` module for more infos.
71 - **Memory barriers**: Calling `glMemoryBarrier` is automatically handled by glium, however you
72 still need to call `memoryBarrier()` in your GLSL code in some situations.
73 - **Programs**: See the `program` module.
74 - **Query objects**: The corresponding structs are in the `draw_parameters` module. They are
75 passed as draw parameters.
76 - **Renderbuffer**: See the `framebuffer` module.
77 - **Render to texture**: If you just want to draw on a texture, you can call
78 `texture.as_surface()`. For more advanced options, see the `framebuffer` module.
79 - **Samplers**: Samplers are automatically managed by glium and are stored in the `Context`
80 object. You can specify how a texture should be sampled by using a `Sampler` dummy object
81 in the `uniforms` module.
82 - **Shaders**: You can't manually create individual shaders. Instead you must create whole
83 programs at once.
84 - **Textures**: Textures are strongly typed and are found in the `texture` module.
85 - **Uniform blocks**: If your program uses uniform blocks, you must pass a reference to a
86 uniform buffer for the name of the block when drawing.
87 - **Vertex array objects**: VAOs are automatically managed by glium if the backend supports them.
88
89*/
90#![warn(missing_docs)]
91
92// TODO: remove these when everything is implemented
93#![allow(dead_code)]
94#![allow(unused_variables)]
95#![allow(
96 clippy::unused_unit,
97 clippy::too_many_arguments,
98 clippy::type_complexity,
99 clippy::module_inception,
100 clippy::neg_cmp_op_on_partial_ord,
101 clippy::missing_safety_doc,
102 clippy::new_without_default,
103 clippy::len_zero,
104 clippy::len_without_is_empty,
105 clippy::if_same_then_else,
106 // Maybe we'll fix these later, but not right now
107 // (Would require API change)
108 clippy::wrong_self_convention,
109)]
110
111#[cfg(feature = "glutin")]
112pub use crate::backend::glutin::glutin;
113#[cfg(feature = "simple_window_builder")]
114pub use crate::backend::winit;
115pub use crate::context::{Capabilities, ExtensionsList, Profile, UuidError};
116pub use crate::draw_parameters::{Blend, BlendingFunction, LinearBlendingFactor, BackfaceCullingMode};
117pub use crate::draw_parameters::{Depth, DepthTest, PolygonMode, DrawParameters, StencilTest, StencilOperation};
118pub use crate::draw_parameters::Smooth;
119pub use crate::index::IndexBuffer;
120pub use crate::vertex::{VertexBuffer, Vertex, VertexFormat};
121pub use crate::program::{Program, ProgramCreationError};
122pub use crate::program::ProgramCreationError::{CompilationError, LinkingError, ShaderTypeNotSupported};
123pub use crate::sync::{LinearSyncFence, SyncFence};
124pub use crate::texture::Texture2d;
125pub use crate::version::{Api, Version, get_supported_glsl_version};
126pub use crate::ops::ReadError;
127
128use std::rc::Rc;
129use std::thread;
130use std::error::Error;
131use std::fmt;
132use std::hash::BuildHasherDefault;
133use std::collections::HashMap;
134
135use fnv::FnvHasher;
136
137use crate::context::Context;
138use crate::context::CommandContext;
139
140#[macro_use]
141mod macros;
142
143pub mod backend;
144pub mod buffer;
145pub mod debug;
146pub mod draw_parameters;
147pub mod framebuffer;
148pub mod index;
149pub mod memory_object;
150pub mod pixel_buffer;
151pub mod program;
152pub mod uniforms;
153pub mod vertex;
154pub mod semaphore;
155pub mod texture;
156pub mod field;
157
158mod context;
159mod fbo;
160mod image_format;
161mod ops;
162mod sampler_object;
163mod sync;
164mod utils;
165mod version;
166mod vertex_array_object;
167
168mod gl {
169 #![allow(clippy::all)]
170 include!(concat!(env!("OUT_DIR"), "/gl_bindings.rs"));
171}
172
173#[doc(hidden)]
174pub use memoffset::offset_of as __glium_offset_of;
175
176/// The main object of this library. Controls the whole display.
177///
178/// This object contains a smart pointer to the real implementation.
179/// Cloning the display allows you to easily share the `Display` object throughout
180/// your program.
181#[cfg(feature = "glutin")]
182pub use crate::backend::glutin::Display;
183
184use crate::uniforms::MagnifySamplerFilter;
185
186/// Trait for objects that describe the capabilities of an OpenGL backend.
187pub trait CapabilitiesSource {
188 /// Returns the version of the backend.
189 fn get_version(&self) -> &version::Version;
190
191 /// Returns the list of extensions that are supported.
192 fn get_extensions(&self) -> &context::ExtensionsList;
193
194 /// Returns the capabilities of the backend.
195 fn get_capabilities(&self) -> &context::Capabilities;
196}
197
198/// Trait for objects that are OpenGL objects.
199pub trait GlObject {
200 /// The type of identifier for this object.
201 type Id;
202
203 /// Returns the id of the object.
204 fn get_id(&self) -> Self::Id;
205}
206
207/// Handle to a shader or a program.
208// TODO: Handle(null()) is equal to Id(0)
209#[derive(PartialEq, Eq, Copy, Clone, Debug, Hash)]
210pub enum Handle {
211 /// A numeric identifier.
212 Id(gl::types::GLuint),
213 /// A `GLhandleARB`.
214 Handle(gl::types::GLhandleARB),
215}
216
217unsafe impl Send for Handle {}
218
219/// Internal trait for enums that can be turned into GLenum.
220trait ToGlEnum {
221 /// Returns the value.
222 fn to_glenum(&self) -> gl::types::GLenum;
223}
224
225/// Internal trait for subbuffers.
226trait BufferExt {
227 /// Returns the number of bytes from the start of the buffer to this subbuffer.
228 fn get_offset_bytes(&self) -> usize;
229
230 /// Calls `glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT)` if necessary.
231 fn prepare_for_vertex_attrib_array(&self, _: &mut CommandContext<'_>);
232
233 /// Calls `glMemoryBarrier(ELEMENT_ARRAY_BARRIER_BIT)` if necessary.
234 fn prepare_for_element_array(&self, _: &mut CommandContext<'_>);
235
236 /// Binds the buffer to `GL_ELEMENT_ARRAY_BUFFER` regardless of the current vertex array object.
237 fn bind_to_element_array(&self, _: &mut CommandContext<'_>);
238
239 /// Makes sure that the buffer is bound to the `GL_PIXEL_PACK_BUFFER` and calls
240 /// `glMemoryBarrier(GL_PIXEL_BUFFER_BARRIER_BIT)` if necessary.
241 fn prepare_and_bind_for_pixel_pack(&self, _: &mut CommandContext<'_>);
242
243 /// Makes sure that nothing is bound to `GL_PIXEL_PACK_BUFFER`.
244 fn unbind_pixel_pack(_: &mut CommandContext<'_>);
245
246 /// Makes sure that the buffer is bound to the `GL_PIXEL_UNPACK_BUFFER` and calls
247 /// `glMemoryBarrier(GL_PIXEL_BUFFER_BARRIER_BIT)` if necessary.
248 fn prepare_and_bind_for_pixel_unpack(&self, _: &mut CommandContext<'_>);
249
250 /// Makes sure that nothing is bound to `GL_PIXEL_UNPACK_BUFFER`.
251 fn unbind_pixel_unpack(_: &mut CommandContext<'_>);
252
253 /// Makes sure that the buffer is bound to the `GL_QUERY_BUFFER` and calls
254 /// `glMemoryBarrier(GL_PIXEL_BUFFER_BARRIER_BIT)` if necessary.
255 fn prepare_and_bind_for_query(&self, _: &mut CommandContext<'_>);
256
257 /// Makes sure that nothing is bound to `GL_QUERY_BUFFER`.
258 fn unbind_query(_: &mut CommandContext<'_>);
259
260 /// Makes sure that the buffer is bound to the `GL_DRAW_INDIRECT_BUFFER` and calls
261 /// `glMemoryBarrier(GL_COMMAND_BARRIER_BIT)` if necessary.
262 fn prepare_and_bind_for_draw_indirect(&self, _: &mut CommandContext<'_>);
263
264 /// Makes sure that the buffer is bound to the `GL_DISPATCH_INDIRECT_BUFFER` and calls
265 /// `glMemoryBarrier(GL_COMMAND_BARRIER_BIT)` if necessary.
266 fn prepare_and_bind_for_dispatch_indirect(&self, _: &mut CommandContext<'_>);
267
268 /// Makes sure that the buffer is bound to the indexed `GL_UNIFORM_BUFFER` point and calls
269 /// `glMemoryBarrier(GL_UNIFORM_BARRIER_BIT)` if necessary.
270 fn prepare_and_bind_for_uniform(&self, _: &mut CommandContext<'_>, index: gl::types::GLuint);
271
272 /// Makes sure that the buffer is bound to the indexed `GL_SHARED_STORAGE_BUFFER` point and calls
273 /// `glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT)` if necessary.
274 fn prepare_and_bind_for_shared_storage(&self, _: &mut CommandContext<'_>, index: gl::types::GLuint);
275
276 /// Makes sure that the buffer is bound to the indexed `GL_ATOMIC_COUNTER_BUFFER` point and calls
277 /// `glMemoryBarrier(GL_ATOMIC_COUNTER_BARRIER_BIT)` if necessary.
278 fn prepare_and_bind_for_atomic_counter(&self, _: &mut CommandContext<'_>, index: gl::types::GLuint);
279
280 /// Binds the buffer to `GL_TRANSFORM_FEEDBACk_BUFFER` regardless of the current transform
281 /// feedback object.
282 fn bind_to_transform_feedback(&self, _: &mut CommandContext<'_>, index: gl::types::GLuint);
283}
284
285/// Internal trait for subbuffer slices.
286trait BufferSliceExt<'a> {
287 /// Tries to get an object where to write a fence.
288 ///
289 /// If this function returns `None`, no fence will be created nor written.
290 fn add_fence(&self) -> Option<buffer::Inserter<'a>>;
291}
292
293/// Internal trait for contexts.
294trait ContextExt {
295 /// Sets whether the context's debug output callback should take errors into account.
296 fn set_report_debug_output_errors(&self, value: bool);
297
298 /// Start executing OpenGL commands by checking the current context.
299 fn make_current(&self) -> context::CommandContext<'_>;
300
301 /// Returns the capabilities of the backend.
302 fn capabilities(&self) -> &context::Capabilities;
303}
304
305/// Internal trait for programs.
306trait ProgramExt {
307 /// Calls `glUseProgram` and enables/disables `GL_PROGRAM_POINT_SIZE` and
308 /// `GL_FRAMEBUFFER_SRGB`.
309 fn use_program(&self, ctxt: &mut context::CommandContext<'_>);
310
311 /// Changes the value of a uniform of the program.
312 fn set_uniform(&self, ctxt: &mut context::CommandContext<'_>, uniform_location: gl::types::GLint,
313 value: &RawUniformValue);
314
315 /// Changes the uniform block binding of the program.
316 fn set_uniform_block_binding(&self, ctxt: &mut context::CommandContext<'_>,
317 block_location: gl::types::GLuint, value: gl::types::GLuint);
318
319 /// Changes the shader storage block binding of the program.
320 fn set_shader_storage_block_binding(&self, ctxt: &mut context::CommandContext<'_>,
321 block_location: gl::types::GLuint,
322 value: gl::types::GLuint);
323
324 /// Changes the subroutine uniform bindings of a program.
325 fn set_subroutine_uniforms_for_stage(&self, ctxt: &mut context::CommandContext<'_>,
326 stage: program::ShaderStage,
327 indices: &[gl::types::GLuint]);
328
329 fn get_uniform(&self, name: &str) -> Option<&program::Uniform>;
330
331 fn get_uniform_blocks(&self) -> &HashMap<String, program::UniformBlock, BuildHasherDefault<FnvHasher>>;
332
333 fn get_shader_storage_blocks(&self) -> &HashMap<String, program::UniformBlock, BuildHasherDefault<FnvHasher>>;
334
335 fn get_atomic_counters(&self) -> &HashMap<String, program::UniformBlock, BuildHasherDefault<FnvHasher>>;
336
337 fn get_subroutine_data(&self) -> &program::SubroutineData;
338}
339
340/// Internal trait for queries.
341trait QueryExt {
342 fn begin_query(&self, ctxt: &mut CommandContext<'_>) -> Result<(), DrawError>;
343
344 fn end_samples_passed_query(ctxt: &mut CommandContext<'_>);
345
346 fn end_time_elapsed_query(ctxt: &mut CommandContext<'_>);
347
348 fn end_primitives_generated_query(ctxt: &mut CommandContext<'_>);
349
350 fn end_transform_feedback_primitives_written_query(ctxt: &mut CommandContext<'_>);
351
352 fn begin_conditional_render(&self, ctxt: &mut CommandContext<'_>, wait: bool, per_region: bool);
353
354 fn end_conditional_render(ctxt: &mut CommandContext<'_>);
355
356 /// Returns true if the query has never been used.
357 fn is_unused(&self) -> bool;
358}
359
360/// Internal trait for textures.
361trait TextureExt {
362 /// Returns the ID of the texture.
363 fn get_texture_id(&self) -> gl::types::GLuint;
364
365 /// Returns the context associated to this texture.
366 fn get_context(&self) -> &Rc<Context>;
367
368 /// Returns the bind point of the texture.
369 fn get_bind_point(&self) -> gl::types::GLenum;
370
371 /// Makes sure that the texture is bound to the current texture unit and returns the
372 /// bind point to use to access the texture (eg. `GL_TEXTURE_2D`, `GL_TEXTURE_3D`, etc.).
373 fn bind_to_current(&self, _: &mut CommandContext<'_>) -> gl::types::GLenum;
374
375 /// Prepares the texture to be accessed, after possibly being modified in a shader
376 /// with image load/store
377 fn prepare_for_access(&self, _: &mut CommandContext<'_>, access_type: TextureAccess);
378}
379
380/// Ways a texture could possibly be accessed after being written to in a shader via an image unit
381enum TextureAccess {
382 /// Regular texture fetches within shaders
383 TextureFetch,
384 /// Texture being used as an image unit inside of a shader
385 ImageUnit { will_write: bool },
386 /// Texture being used as a framebuffer object
387 Framebuffer,
388}
389
390/// Internal trait for textures.
391trait TextureMipmapExt {
392 /// Changes some parts of the texture.
393 fn upload_texture<'a, P>(&self, x_offset: u32, y_offset: u32, z_offset: u32,
394 _: (image_format::ClientFormatAny, std::borrow::Cow<'a, [P]>), width: u32,
395 height: Option<u32>, depth: Option<u32>,
396 regen_mipmaps: bool)
397 -> Result<(), ()> // TODO return a better Result!?
398 where P: Send + Copy + Clone + 'a;
399
400 fn download_compressed_data(&self) -> Option<(image_format::ClientFormatAny, Vec<u8>)>;
401}
402
403/// Internal trait for transform feedback sessions.
404trait TransformFeedbackSessionExt {
405 /// Updates the state of OpenGL to make the transform feedback session current.
406 ///
407 /// The second parameter must be the primitive type of the input vertex data.
408 fn bind(&self, _: &mut CommandContext<'_>, _: index::PrimitiveType);
409
410 /// Ensures that transform feedback is disabled.
411 fn unbind(_: &mut CommandContext<'_>);
412
413 /// Ensures that a buffer isn't used by transform feedback.
414 fn ensure_buffer_out_of_transform_feedback(_: &mut CommandContext<'_>, _: gl::types::GLuint);
415}
416
417/// Internal trait for uniforms handling.
418trait UniformsExt {
419 /// Binds the uniforms to a given program.
420 ///
421 /// Will replace texture and buffer bind points.
422 fn bind_uniforms<'a, P>(&'a self, _: &mut CommandContext<'_>, _: &P, _: &mut Vec<buffer::Inserter<'a>>)
423 -> Result<(), DrawError> where P: ProgramExt;
424}
425
426
427/// A raw value of a uniform. "Raw" means that it's passed directly with `glUniform`. Textures
428/// for example are just passed as integers.
429///
430/// Blocks and subroutines are not included.
431#[derive(Copy, Clone, Debug)]
432#[allow(missing_docs)]
433pub enum RawUniformValue {
434 SignedInt(gl::types::GLint),
435 UnsignedInt(gl::types::GLuint),
436 Float(gl::types::GLfloat),
437 /// 2x2 column-major matrix.
438 Mat2([[gl::types::GLfloat; 2]; 2]),
439 /// 3x3 column-major matrix.
440 Mat3([[gl::types::GLfloat; 3]; 3]),
441 /// 4x4 column-major matrix.
442 Mat4([[gl::types::GLfloat; 4]; 4]),
443 Vec2([gl::types::GLfloat; 2]),
444 Vec3([gl::types::GLfloat; 3]),
445 Vec4([gl::types::GLfloat; 4]),
446 IntVec2([gl::types::GLint; 2]),
447 IntVec3([gl::types::GLint; 3]),
448 IntVec4([gl::types::GLint; 4]),
449 UnsignedIntVec2([gl::types::GLuint; 2]),
450 UnsignedIntVec3([gl::types::GLuint; 3]),
451 UnsignedIntVec4([gl::types::GLuint; 4]),
452
453 // Double precision primitives
454 Double(gl::types::GLdouble),
455 DoubleMat2([[gl::types::GLdouble; 2]; 2]),
456 DoubleMat3([[gl::types::GLdouble; 3]; 3]),
457 DoubleMat4([[gl::types::GLdouble; 4]; 4]),
458 DoubleVec2([gl::types::GLdouble; 2]),
459 DoubleVec3([gl::types::GLdouble; 3]),
460 DoubleVec4([gl::types::GLdouble; 4]),
461 Int64(gl::types::GLint64),
462 Int64Vec2([gl::types::GLint64; 2]),
463 Int64Vec3([gl::types::GLint64; 3]),
464 Int64Vec4([gl::types::GLint64; 4]),
465 UnsignedInt64(gl::types::GLuint64),
466 UnsignedInt64Vec2([gl::types::GLuint64; 2]),
467 UnsignedInt64Vec3([gl::types::GLuint64; 3]),
468 UnsignedInt64Vec4([gl::types::GLuint64; 4]),
469}
470
471/// Area of a surface in pixels.
472///
473/// In the OpenGL ecosystem, the (0,0) coordinate is at the bottom-left hand corner of the images.
474#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
475pub struct Rect {
476 /// Number of pixels between the left border of the surface and the left border of
477 /// the rectangle.
478 pub left: u32,
479 /// Number of pixels between the bottom border of the surface and the bottom border
480 /// of the rectangle.
481 pub bottom: u32,
482 /// Width of the area in pixels.
483 pub width: u32,
484 /// Height of the area in pixels.
485 pub height: u32,
486}
487
488/// Area of a surface in pixels. Similar to a `Rect` except that dimensions can be negative.
489///
490/// In the OpenGL ecosystem, the (0,0) coordinate is at the bottom-left hand corner of the images.
491#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
492pub struct BlitTarget {
493 /// Number of pixels between the left border of the surface and the left border of
494 /// the rectangle.
495 pub left: u32,
496 /// Number of pixels between the bottom border of the surface and the bottom border
497 /// of the rectangle.
498 pub bottom: u32,
499 /// Width of the area in pixels. Can be negative.
500 pub width: i32,
501 /// Height of the area in pixels. Can be negative.
502 pub height: i32,
503}
504
505/// Mask specifying, which kinds of buffers to copy when blitting between two frame buffers.
506#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
507pub struct BlitMask {
508
509 /// If the color buffer should be copied.
510 pub color: bool,
511
512 /// If the depth buffer should be copied.
513 pub depth: bool,
514
515 /// If the stencil buffer should be copied.
516 pub stencil: bool,
517}
518
519impl BlitMask {
520
521 /// Constructs a bit mask, that will only copy the color buffer
522 pub fn color() -> Self {
523 BlitMask { color: true, depth: false, stencil: false }
524 }
525
526 /// Constructs a bit mask, that will only copy the depth buffer
527 pub fn depth() -> Self {
528 BlitMask { color: false, depth: true, stencil: false }
529 }
530
531 /// Constructs a bit mask, that will only copy the stencil buffer
532 pub fn stencil() -> Self {
533 BlitMask { color: false, depth: false, stencil: true }
534 }
535
536 /// Constructs a bit mask, that will copy the color and the depth buffer.
537 pub fn color_and_depth() -> Self {
538 BlitMask { color: true, depth: true, stencil: false }
539 }
540
541 /// Constructs a bit mask, that will copy the color and the stencil buffer.
542 pub fn color_and_stencil() -> Self {
543 BlitMask { color: true, depth: false, stencil: true }
544 }
545
546 /// Constructs a bit mask, that will copy the depth and the stencil buffer.
547 pub fn depth_and_stencil() -> Self {
548 BlitMask { color: false, depth: true, stencil: true }
549 }
550
551 /// Constructs a bit mask, that will copy the color, depth and stencil buffer.
552 pub fn color_and_depth_and_stencil() -> Self {
553 BlitMask { color: true, depth: true, stencil: true }
554 }
555}
556
557impl ToGlEnum for BlitMask {
558 #[inline]
559 fn to_glenum(&self) -> gl::types::GLenum {
560 let mut mask = 0;
561 if self.color {
562 mask = mask | gl::COLOR_BUFFER_BIT;
563 }
564 if self.depth {
565 mask = mask | gl::DEPTH_BUFFER_BIT;
566 }
567 if self.stencil {
568 mask = mask | gl::STENCIL_BUFFER_BIT;
569 }
570 mask
571 }
572}
573
574/// Object that can be drawn upon.
575///
576/// # What does the GPU do when you draw?
577///
578/// This is a summary of everything that happens when you call the `draw` function. Note that
579/// this is not necessarily *exactly* what happens. Backends are free to do whatever they want
580/// as long as it always matches the expected outcome.
581///
582/// ## Step 1: Vertex shader
583///
584/// For each vertex in the vertices source, the GPU invokes the vertex shader that is part
585/// of the program, and passes the corresponding vertex's attributes to it.
586///
587/// The vertex shader *must* write the special `gl_Position` variable in order to indicate
588/// the four-dimensions coordinates of the vertex. In order to understand what these coordinates
589/// mean, see the "vertex post-processing" step below.
590///
591/// In addition to the position of the vertex, the vertex shader can also specify the values of
592/// various vertex attributes.
593///
594/// ## Step 2: Tessellation (optional)
595///
596///
597/// ## Step 3: Geometry shader (optional)
598///
599/// If you specify a geometry shader, then the GPU will invoke it once for each primitive.
600///
601/// The geometry shader can output multiple primitives.
602///
603/// ## Step 4: Transform feedback (optional)
604///
605/// TODO:
606/// TODO: talk about `transform_feedback_primitives_written_query` as well
607///
608/// ## Step 5: Vertex post-processing
609///
610/// The vertex shader step told the GPU what the coordinates of each vertex are, but these
611/// coordinates have four dimensions, named `x`, `y`, `z` and `w`.
612///
613/// The GPU then computes the position of the vertex on the 2D surface you are drawing on, and
614/// the depth of this vertex:
615///
616/// ```notrust
617/// window_x = viewport_left + viewport_width * ((x / w) + 1.0) / 2.0
618/// window_y = viewport_bottom + viewport_height * ((y / w) + 1.0) / 2.0
619/// depth = depth_near + (depth_far - depth_near) * ((z / w) + 1.0) / 2.0
620/// ```
621///
622/// *`viewport_left`, `viewport_width`, `viewport_bottom` and `viewport_height` correspond to
623/// the `viewport` member of the draw parameters, and `depth_near` and `depth_far` correspond
624/// to the `depth_range` member*.
625///
626/// This means that if `x / w`, `y / w` or `z / w` are equal to `-1.0`, then the result will be
627/// `viewport_left`, `viewport_bottom` or `depth_near`. If they are equal to `1.0`, the result
628/// will be `viewport_left + viewport_width` (the right of the viewport),
629/// `viewport_bottom + viewport_height` (the top of the viewport) or `depth_far`.
630///
631/// For example if you want to draw a rectangle that covers the whole screen, it should be made
632/// of four vertices whose coordinates are `(-1.0, -1.0, 0.0, 1.0)` (bottom-left corner),
633/// `(-1.0, 1.0, 0.0, 1.0)` (top-left corner), `(1.0, 1.0, 0.0, 1.0)` (top-right corner) and
634/// `(1.0, -1.0, 0.0, 1.0)` (bottom-right corner).
635///
636/// ## Step 6: Primitive assembly
637///
638/// The next step consists in building the primitives. Triangle strips, triangle fans and line
639/// strips are turned into individual triangles or lines.
640///
641/// Triangle strips obey certain rules for the order of indices. For example the triangle strip
642/// `0, 1, 2, 3, 4, 5` does *not* correspond to `0, 1, 2`, `1, 2, 3`, `2, 3, 4`, `3, 4, 5` as you
643/// would expect, but to `0, 1, 2`, `1, 3, 2`, `2, 3, 4`, `3, 5, 4` (some indices are reversed).
644/// This is important with regards to the face culling step below.
645///
646/// Then, if you did specify `PrimitiveMode`, it is used. If you specified `Line`, triangles are
647/// turned into lines. If specified `Point`, triangles and lines are turned into points.
648///
649/// The GPU then looks at the screen coordinates of each primitive, and discards primitives that
650/// are entirely outside of the window.
651///
652/// Note that points whose centers are outside of the viewport are discarded, even if the point
653/// width would be big enough for the point to be visible. However this standard behavior is not
654/// respected by nVidia drivers, which show the points anyway.
655///
656/// If a query has been specified through `primitives_generated_query`, then its value is updated.
657///
658/// ## Step 7: Face culling (triangles only)
659///
660/// This step is purely an optimization step and only concerns triangles.
661///
662/// If you specify a value for `backface_culling` other than `CullingDisabled`, the GPU will
663/// discard triangles depending on the way that the vertices are arranged on the window. You can
664/// either discard triangles whose vertices are clockwise or counterclockwise.
665///
666/// For more information, see the `BackfaceCullingMode` documentation.
667///
668/// ## Step 8: Rasterization
669///
670/// Now that the GPU knows where on the window the various triangles, points or lines are, it will
671/// determine which pixels of the surface are part of each primitive.
672///
673/// For points and lines, this step depends on the points width and line width that you specified
674/// in the draw parameters. If you specify the `smooth` parameter, then the borders of the
675/// primitives will see their alpha value adjusted.
676///
677/// <img alt="" src="data:image/png;base64,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" />
678///
679/// The attributes of each vertex that are marked as `smooth` (which is the default value) are
680/// being interpolated, and the GPU assigns a value for each attribute for each pixel.
681///
682/// ## Step 9: Fragment shader
683///
684/// The GPU now executes the fragment shader once for each pixel of each primitive.
685/// The vertex attributes that were interpolated at the previous step are passed to the fragment
686/// shader.
687///
688/// The fragment shader must return the color to write by setting the value of `gl_FragColor`.
689///
690/// If the target framebuffer has multisampling enabled, then each pixel of the target image is
691/// in turn split into four subpixels. The output of the fragment shader is copied and written into
692/// each subpixel. If `multisampling` in the draw parameters is `true` (its default value), only
693/// subpixels that belong to the triangle are written.
694///
695/// If a query has been specified through `samples_passed_query`, then its value is updated.
696///
697/// ## Step 10: Pixel ownership
698///
699/// This step is mostly an implementation detail. If the window you are drawing on is not on the
700/// foreground, or if it is partially obstructed, then the pixels that are not on the
701/// foreground will be discarded.
702///
703/// This is only relevant if you draw to the default framebuffer.
704///
705/// This step has to be taken into account in some situations. For example if you query the number
706/// of samples that have been written, the ones that don't pass the pixel ownership test won't
707/// count.
708///
709/// ## Step 11: Scissor test
710///
711/// If `scissor` has been specified, then all the pixels that are outside of this rect
712/// are discarded.
713///
714/// ## Step 12: Depth test
715///
716/// In addition to the colors, surfaces can also have a depth buffer attached to it. In this
717/// situation, just like each pixel has a color, each pixel of the surface also has an associated
718/// depth value.
719///
720/// If a depth buffer is present, the GPU will compare the depth value of the pixel currently
721/// being processed, with the existing depth value. Depending on the value of `depth_test`
722/// in the draw parameters, the depth test will either pass, in which case the pipeline
723/// continues, or fail, in which case the pixel is discarded. If the value of `depth_write`
724/// is true and the test passed, it will then also write the depth value of the pixel on the
725/// depth buffer.
726///
727/// The purpose of this test is to avoid drawing elements that are in the background of the
728/// scene over elements that are in the foreground.
729///
730/// See the documentation of `DepthTest` for more informations.
731///
732/// ## Step 13: Stencil test
733///
734/// Similar to the depth buffer, surfaces can also have a stencil buffer.
735///
736/// The `stencil_test_clockwise` and `stencil_test_counter_clockwise` draw parameters specify
737/// the operation to use to check whether or not each pixel passes the stencil test. Pixels that
738/// fail the stencil test won't be drawn on the screen.
739///
740/// The `*_clockwise` members are relevant for polygons that are displayed clockwise, and the
741/// `*_counter_clockwise` members are relevant for polygons that are displayed counterclockwise.
742/// See also the `face culling` step for more infos. Lines and points always use the `*_clockwise`
743/// members.
744///
745/// There are three possibilities for each pixel: either it fails the stencil test, or it passes
746/// the stencil test but failed the depth test, or it passes both the stencil test and depth test.
747/// You can specify for each of these three situations what to do with the value in the stencil
748/// buffer with the draw parameters.
749///
750/// ## Step 14: Blending
751///
752/// For each pixel to write, the GPU takes the RGBA color that the fragment shader has returned
753/// and the existing RGBA color already written on the surface, and merges the two.
754///
755/// The way they are merged depends on the value of `blending_function`. This allows you to choose
756/// how alpha colors are merged together.
757///
758/// See the documentation of `BlendingFunction` fore more informations.
759///
760/// ## Step 15: Dithering (optional)
761///
762/// If `dithering` is `true` in the draw parameters, then a dithering algorithm is applied.
763///
764/// When you draw a gradient of colors, the boundary between each individual color value is
765/// visible. Thanks to an optical illusion, a dithering algorithm will change the color values
766/// of some pixels and hide the boundaries.
767///
768/// ## Step 16: Conversion to sRGB
769///
770/// If the target has sRGB enabled, then the output of the fragment will get some gamma correction.
771///
772/// Monitors don't show colors linearly. For example a value of `0.5` isn't shown half as bright
773/// as a value of `1.0`. Instead the monitor will show colors as darker than they should be.
774/// In order to fix this problem, each pixel is modified to be made slightly brighter with the same
775/// factor as the monitor makes them darker.
776///
777/// ## Step 17: End
778///
779/// This is finally the step where colors are being written. The `color_mask` parameter allow you
780/// to specify whether each color component (red, green, blue and alpha) is written to the color
781/// buffer.
782///
783pub trait Surface {
784 /// Clears some attachments of the target.
785 fn clear(&mut self, rect: Option<&Rect>, color: Option<(f32, f32, f32, f32)>, color_srgb: bool,
786 depth: Option<f32>, stencil: Option<i32>);
787
788 /// Clears the color attachment of the target. The color is converted to sRGB when the target has sRGB format.
789 fn clear_color(&mut self, red: f32, green: f32, blue: f32, alpha: f32) {
790 self.clear(None, Some((red, green, blue, alpha)), false, None, None);
791 }
792
793 /// Clears the color attachment of the target. The color is in sRGB format and is not converted in the target.
794 fn clear_color_srgb(&mut self, red: f32, green: f32, blue: f32, alpha: f32) {
795 self.clear(None, Some((red, green, blue, alpha)), true, None, None);
796 }
797
798 /// Clears the depth attachment of the target.
799 fn clear_depth(&mut self, value: f32) {
800 self.clear(None, None, false, Some(value), None);
801 }
802
803 /// Clears the stencil attachment of the target.
804 fn clear_stencil(&mut self, value: i32) {
805 self.clear(None, None, false, None, Some(value));
806 }
807
808 /// Clears the color and depth attachments of the target.
809 fn clear_color_and_depth(&mut self, color: (f32, f32, f32, f32), depth: f32) {
810 self.clear(None, Some(color), false, Some(depth), None);
811 }
812
813 /// Clears the color and depth attachments of the target. The color is in sRGB format.
814 fn clear_color_srgb_and_depth(&mut self, color: (f32, f32, f32, f32), depth: f32) {
815 self.clear(None, Some(color), true, Some(depth), None);
816 }
817
818 /// Clears the color and stencil attachments of the target.
819 fn clear_color_and_stencil(&mut self, color: (f32, f32, f32, f32), stencil: i32) {
820 self.clear(None, Some(color), false, None, Some(stencil));
821 }
822
823 /// Clears the color and stencil attachments of the target. The color is in sRGB format.
824 fn clear_color_srgb_and_stencil(&mut self, color: (f32, f32, f32, f32), stencil: i32) {
825 self.clear(None, Some(color), true, None, Some(stencil));
826 }
827
828 /// Clears the depth and stencil attachments of the target.
829 fn clear_depth_and_stencil(&mut self, depth: f32, stencil: i32) {
830 self.clear(None, None, false, Some(depth), Some(stencil));
831 }
832
833 /// Clears the color, depth and stencil attachments of the target.
834 fn clear_all(&mut self, color: (f32, f32, f32, f32), depth: f32, stencil: i32) {
835 self.clear(None, Some(color), false, Some(depth), Some(stencil));
836 }
837
838 /// Clears the color, depth and stencil attachments of the target. The color is in sRGB format.
839 fn clear_all_srgb(&mut self, color: (f32, f32, f32, f32), depth: f32, stencil: i32) {
840 self.clear(None, Some(color), true, Some(depth), Some(stencil));
841 }
842
843 /// Returns the dimensions in pixels of the target.
844 fn get_dimensions(&self) -> (u32, u32);
845
846 /// Returns the number of bits of each pixel of the depth buffer.
847 ///
848 /// Returns `None` if there is no depth buffer.
849 fn get_depth_buffer_bits(&self) -> Option<u16>;
850
851 /// Returns true if the surface has a depth buffer available.
852 fn has_depth_buffer(&self) -> bool {
853 self.get_depth_buffer_bits().is_some()
854 }
855
856 /// Returns the number of bits of each pixel of the stencil buffer.
857 ///
858 /// Returns `None` if there is no stencil buffer.
859 fn get_stencil_buffer_bits(&self) -> Option<u16>;
860
861 /// Returns true if the surface has a stencil buffer available.
862 fn has_stencil_buffer(&self) -> bool {
863 self.get_stencil_buffer_bits().is_some()
864 }
865
866 /// Draws.
867 ///
868 /// This is probably the most complex function of glium. Check out the rest of the
869 /// documentation for example how to use it.
870 ///
871 /// See above for what happens exactly on the GPU when you draw.
872 fn draw<'a, 'b, V, I, U>(&mut self, _: V, _: I, program: &Program, uniforms: &U,
873 draw_parameters: &DrawParameters<'_>) -> Result<(), DrawError> where
874 V: vertex::MultiVerticesSource<'b>, I: Into<index::IndicesSource<'a>>,
875 U: uniforms::Uniforms;
876
877 /// Blits from the default framebuffer.
878 #[inline]
879 fn blit_from_frame(&self, source_rect: &Rect, target_rect: &BlitTarget,
880 filter: uniforms::MagnifySamplerFilter)
881 {
882 self.blit_buffers_from_frame(source_rect, target_rect, filter, BlitMask::color())
883 }
884
885 /// Blits from a simple framebuffer.
886 #[inline]
887 fn blit_from_simple_framebuffer(&self, source: &framebuffer::SimpleFrameBuffer<'_>,
888 source_rect: &Rect, target_rect: &BlitTarget,
889 filter: uniforms::MagnifySamplerFilter)
890 {
891 self.blit_buffers_from_simple_framebuffer(source, source_rect, target_rect, filter,
892 BlitMask::color())
893 }
894
895 /// Blits from a multi-output framebuffer.
896 #[inline]
897 fn blit_from_multioutput_framebuffer(&self, source: &framebuffer::MultiOutputFrameBuffer<'_>,
898 source_rect: &Rect, target_rect: &BlitTarget,
899 filter: uniforms::MagnifySamplerFilter)
900 {
901 self.blit_buffers_from_multioutput_framebuffer(source, source_rect, target_rect, filter,
902 BlitMask::color())
903 }
904
905 /// Blits from the default framebuffer.
906 fn blit_buffers_from_frame(&self, source_rect: &Rect, target_rect: &BlitTarget,
907 filter: uniforms::MagnifySamplerFilter, mask: BlitMask);
908
909 /// Blits from a simple framebuffer.
910 fn blit_buffers_from_simple_framebuffer(&self, source: &framebuffer::SimpleFrameBuffer<'_>,
911 source_rect: &Rect, target_rect: &BlitTarget,
912 filter: uniforms::MagnifySamplerFilter,
913 mask: BlitMask);
914
915 /// Blits from a multi-output framebuffer.
916 fn blit_buffers_from_multioutput_framebuffer(&self, source: &framebuffer::MultiOutputFrameBuffer<'_>,
917 source_rect: &Rect, target_rect: &BlitTarget,
918 filter: uniforms::MagnifySamplerFilter,
919 mask: BlitMask);
920
921
922 /// Copies a rectangle of pixels from this surface to another surface.
923 ///
924 /// The `source_rect` defines the area of the source (`self`) that will be copied, and the
925 /// `target_rect` defines the area where the copied image will be pasted. If the source and
926 /// target areas don't have the same dimensions, the image will be resized to match.
927 /// The `filter` parameter is relevant only in this situation.
928 ///
929 /// It is possible for the source and the target to be the same surface. However if the
930 /// rectangles overlap, then the behavior is undefined.
931 ///
932 /// Note that there is no alpha blending, depth/stencil checking, etc. This function just
933 /// copies pixels.
934 fn blit_color<S>(&self, source_rect: &Rect, target: &S, target_rect: &BlitTarget,
935 filter: uniforms::MagnifySamplerFilter) where S: Surface;
936
937
938 /// Copies the entire surface to a target surface. See `blit_color`.
939 #[inline]
940 fn blit_whole_color_to<S>(&self, target: &S, target_rect: &BlitTarget,
941 filter: uniforms::MagnifySamplerFilter) where S: Surface
942 {
943 let src_dim = self.get_dimensions();
944 let src_rect = Rect { left: 0, bottom: 0, width: src_dim.0 as u32, height: src_dim.1 as u32 };
945 self.blit_color(&src_rect, target, target_rect, filter)
946 }
947
948 /// Copies the entire surface to the entire target. See `blit_color`.
949 #[inline]
950 fn fill<S>(&self, target: &S, filter: uniforms::MagnifySamplerFilter) where S: Surface {
951 let src_dim = self.get_dimensions();
952 let src_rect = Rect { left: 0, bottom: 0, width: src_dim.0 as u32, height: src_dim.1 as u32 };
953 let target_dim = target.get_dimensions();
954 let target_rect = BlitTarget { left: 0, bottom: 0, width: target_dim.0 as i32, height: target_dim.1 as i32 };
955 self.blit_color(&src_rect, target, &target_rect, filter)
956 }
957}
958
959/// Private trait for framebuffer-like objects that provide attachments.
960trait FboAttachments {
961 /// Returns the list of attachments of this FBO, or `None` if it is the default framebuffer.
962 fn get_attachments(&self) -> Option<&fbo::ValidatedAttachments<'_>>;
963}
964
965/// Error that can happen while drawing.
966#[derive(Clone, Debug)]
967pub enum DrawError {
968 /// A depth function has been requested but no depth buffer is available.
969 NoDepthBuffer,
970
971 /// The type of a vertex attribute in the vertices source doesn't match what the
972 /// program requires.
973 AttributeTypeMismatch,
974
975 /// One of the attributes required by the program is missing from the vertex format.
976 ///
977 /// Note that it is perfectly valid to have an attribute in the vertex format that is
978 /// not used by the program.
979 AttributeMissing,
980
981 /// The viewport's dimensions are not supported by the backend.
982 ViewportTooLarge,
983
984 /// The depth range is outside of the `(0, 1)` range.
985 InvalidDepthRange,
986
987 /// The type of a uniform doesn't match what the program requires.
988 UniformTypeMismatch {
989 /// Name of the uniform you are trying to bind.
990 name: String,
991 /// The expected type.
992 expected: uniforms::UniformType,
993 },
994
995 /// Tried to bind a uniform buffer to a single uniform value.
996 UniformBufferToValue {
997 /// Name of the uniform you are trying to bind.
998 name: String,
999 },
1000
1001 /// Tried to bind a single uniform value to a uniform block.
1002 UniformValueToBlock {
1003 /// Name of the uniform you are trying to bind.
1004 name: String,
1005 },
1006
1007 /// The layout of the content of the uniform buffer does not match the layout of the block.
1008 UniformBlockLayoutMismatch {
1009 /// Name of the block you are trying to bind.
1010 name: String,
1011 /// The error giving more details about the mismatch.
1012 err: uniforms::LayoutMismatchError,
1013 },
1014
1015 /// Tried to bind a subroutine uniform like a regular uniform value.
1016 SubroutineUniformToValue {
1017 /// Name of the uniform you are trying to bind.
1018 name: String,
1019 },
1020
1021 /// Not all subroutine uniforms of a shader stage were set.
1022 SubroutineUniformMissing {
1023 /// Shader stage with missing bindings.
1024 stage: program::ShaderStage,
1025 /// The expected number of bindings.
1026 expected_count: usize,
1027 /// The number of bindings defined by the user.
1028 real_count: usize,
1029
1030 },
1031
1032 /// A non-existent subroutine was referenced.
1033 SubroutineNotFound {
1034 /// The stage the subroutine was searched for.
1035 stage: program::ShaderStage,
1036 /// The invalid name of the subroutine.
1037 name: String
1038 },
1039
1040 /// The number of vertices per patch that has been requested is not supported.
1041 UnsupportedVerticesPerPatch,
1042
1043 /// Trying to use tessellation, but this is not supported by the underlying hardware.
1044 TessellationNotSupported,
1045
1046 /// Using a program which contains tessellation shaders, but without submitting patches.
1047 TessellationWithoutPatches,
1048
1049 /// Trying to use a sampler, but they are not supported by the backend.
1050 SamplersNotSupported,
1051
1052 /// When you use instancing, all vertices sources must have the same size.
1053 InstancesCountMismatch,
1054
1055 /// If you don't use indices, then all vertices sources must have the same size.
1056 VerticesSourcesLengthMismatch,
1057
1058 /// You requested not to draw primitives, but this is not supported by the backend.
1059 TransformFeedbackNotSupported,
1060
1061 /// See the documentation of the `draw_parameters` module for infos.
1062 WrongQueryOperation,
1063
1064 /// You requested smoothing, but this is not supported by the backend.
1065 SmoothingNotSupported,
1066
1067 /// The requested provoking vertex is not supported by the backend.
1068 ProvokingVertexNotSupported,
1069
1070 /// Discarding rasterizer output isn't supported by the backend.
1071 RasterizerDiscardNotSupported,
1072
1073 /// Depth clamping isn't supported by the backend.
1074 DepthClampNotSupported,
1075
1076 /// One of the blending parameters is not supported by the backend.
1077 BlendingParameterNotSupported,
1078
1079 /// Restarting indices (multiple objects per draw call) is not supported by the backend.
1080 FixedIndexRestartingNotSupported,
1081
1082 /// Changing the clip volume definition (origin and depth mode) is not supported by the backend.
1083 ClipControlNotSupported,
1084
1085 /// Tried to enable a clip plane that does not exist.
1086 ClipPlaneIndexOutOfBounds,
1087
1088 /// Tried to use too many image units simultaneously
1089 InsufficientImageUnits,
1090}
1091
1092impl Error for DrawError {
1093 fn source(&self) -> Option<&(dyn Error + 'static)> {
1094 use self::DrawError::*;
1095 match *self {
1096 UniformBlockLayoutMismatch { ref err, .. } => Some(err),
1097 _ => None,
1098 }
1099 }
1100}
1101
1102
1103impl fmt::Display for DrawError {
1104 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
1105 use self::DrawError::*;
1106 let desc = match self {
1107 NoDepthBuffer =>
1108 "A depth function has been requested but no depth buffer is available",
1109 AttributeTypeMismatch =>
1110 "The type of a vertex attribute in the vertices source doesn't match what the program requires",
1111 AttributeMissing =>
1112 "One of the attributes required by the program is missing from the vertex format",
1113 ViewportTooLarge =>
1114 "The viewport's dimensions are not supported by the backend",
1115 InvalidDepthRange =>
1116 "The depth range is outside of the `(0, 1)` range",
1117 UniformTypeMismatch { .. } =>
1118 "The type of a uniform doesn't match what the program requires",
1119 UniformBufferToValue { .. } =>
1120 "Tried to bind a uniform buffer to a single uniform value",
1121 UniformValueToBlock { .. } =>
1122 "Tried to bind a single uniform value to a uniform block",
1123 UniformBlockLayoutMismatch { .. } =>
1124 "The layout of the content of the uniform buffer does not match the layout of the block",
1125 SubroutineUniformToValue { .. } =>
1126 "Tried to bind a subroutine uniform like a regular uniform value",
1127 SubroutineUniformMissing { .. } =>
1128 "Not all subroutine uniforms of a shader stage were set",
1129 SubroutineNotFound { .. } =>
1130 "A non-existent subroutine was referenced",
1131 UnsupportedVerticesPerPatch =>
1132 "The number of vertices per patch that has been requested is not supported",
1133 TessellationNotSupported =>
1134 "Trying to use tessellation, but this is not supported by the underlying hardware",
1135 TessellationWithoutPatches =>
1136 "Using a program which contains tessellation shaders, but without submitting patches",
1137 SamplersNotSupported => "
1138 Trying to use a sampler, but they are not supported by the backend",
1139 InstancesCountMismatch =>
1140 "When you use instancing, all vertices sources must have the same size",
1141 VerticesSourcesLengthMismatch =>
1142 "If you don't use indices, then all vertices sources must have the same size",
1143 TransformFeedbackNotSupported =>
1144 "Requested not to draw primitives, but this is not supported by the backend",
1145 WrongQueryOperation =>
1146 "Wrong query operation",
1147 SmoothingNotSupported =>
1148 "Trying to use smoothing, but this is not supported by the backend",
1149 ProvokingVertexNotSupported =>
1150 "Trying to set the provoking vertex, but this is not supported by the backend",
1151 RasterizerDiscardNotSupported =>
1152 "Discarding rasterizer output is not supported by the backend",
1153 DepthClampNotSupported =>
1154 "The depth clamp mode is not supported by the backend",
1155 BlendingParameterNotSupported =>
1156 "One the blending parameters is not supported by the backend",
1157 FixedIndexRestartingNotSupported =>
1158 "Restarting indices (multiple objects per draw call) is not supported by the backend",
1159 ClipControlNotSupported =>
1160 "Changing the clip volume definition (origin and depth mode) is not supported by the backend",
1161 ClipPlaneIndexOutOfBounds =>
1162 "Tried to enable a clip plane that does not exist.",
1163 InsufficientImageUnits =>
1164 "Tried to use more image uniforms that the implementation has support for",
1165 };
1166 match self {
1167 UniformTypeMismatch { ref name, ref expected } =>
1168 write!(
1169 fmt,
1170 "{}, got: {:?}, expected: {:?}",
1171 desc,
1172 name,
1173 expected,
1174 ),
1175 UniformBufferToValue { name } =>
1176 write!(
1177 fmt,
1178 "{}: {}",
1179 desc,
1180 name,
1181 ),
1182 UniformValueToBlock { name } =>
1183 write!(
1184 fmt,
1185 "{}: {}",
1186 desc,
1187 name,
1188 ),
1189 UniformBlockLayoutMismatch { name, err } =>
1190 write!(
1191 fmt,
1192 "{}: {}, caused by {}",
1193 desc,
1194 name,
1195 err,
1196 ),
1197 _ =>
1198 fmt.write_str(desc),
1199 }
1200 }
1201}
1202
1203/// Error that can happen when swapping buffers.
1204#[derive(Debug, Copy, Clone, PartialEq, Eq)]
1205pub enum SwapBuffersError {
1206 /// The OpenGL context has been lost and needs to be recreated. The `Display` and all the
1207 /// objects associated to it (textures, buffers, programs, etc.) need to be recreated from
1208 /// scratch.
1209 ///
1210 /// Operations will have no effect. Functions that read textures, buffers, etc. from OpenGL
1211 /// will return uninitialized data instead.
1212 ///
1213 /// A context loss usually happens on mobile devices when the user puts the application on
1214 /// sleep and wakes it up later. However any OpenGL implementation can theoretically lose the
1215 /// context at any time. Can only happen if calling `is_context_loss_possible()` returns true.
1216 ContextLost,
1217 /// The buffers have already been swapped.
1218 ///
1219 /// This error can be returned when `set_finish()` is called multiple times, or `finish()` is
1220 /// called after `set_finish()`.
1221 AlreadySwapped,
1222}
1223
1224impl Error for SwapBuffersError {}
1225
1226impl fmt::Display for SwapBuffersError {
1227 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
1228 use self::SwapBuffersError::*;
1229 let desc = match *self {
1230 ContextLost =>
1231 "the OpenGL context has been lost and needs to be recreated",
1232 AlreadySwapped =>
1233 "the buffers have already been swapped",
1234 };
1235 fmt.write_str(desc)
1236 }
1237}
1238
1239/// Implementation of `Surface`, targeting the default framebuffer.
1240///
1241/// The back- and front-buffers are swapped when you call `finish`.
1242///
1243/// You **must** call either `finish` or `set_finish` or else the destructor will panic.
1244pub struct Frame {
1245 context: Rc<Context>,
1246 dimensions: (u32, u32),
1247 destroyed: bool, // TODO: use a linear type instead.
1248}
1249
1250impl Frame {
1251 /// Builds a new `Frame`. Use the `draw` function on `Display` instead of this function.
1252 #[inline]
1253 pub fn new(context: Rc<Context>, dimensions: (u32, u32)) -> Frame {
1254 Frame {
1255 context,
1256 dimensions,
1257 destroyed: false,
1258 }
1259 }
1260
1261 /// Stop drawing, swap the buffers, and consume the Frame.
1262 ///
1263 /// See the documentation of `SwapBuffersError` about what is being returned.
1264 #[inline]
1265 pub fn finish(mut self) -> Result<(), SwapBuffersError> {
1266 self.set_finish()
1267 }
1268
1269 /// Stop drawing, swap the buffers.
1270 ///
1271 /// The Frame can now be dropped regularly. Calling `finish()` or `set_finish()` again will
1272 /// cause `Err(SwapBuffersError::AlreadySwapped)` to be returned.
1273 #[inline]
1274 pub fn set_finish(&mut self) -> Result<(), SwapBuffersError> {
1275 if self.destroyed {
1276 return Err(SwapBuffersError::AlreadySwapped);
1277 }
1278
1279 self.destroyed = true;
1280 self.context.swap_buffers()
1281 }
1282}
1283
1284impl Surface for Frame {
1285 #[inline]
1286 fn clear(&mut self, rect: Option<&Rect>, color: Option<(f32, f32, f32, f32)>, color_srgb: bool,
1287 depth: Option<f32>, stencil: Option<i32>)
1288 {
1289 ops::clear(&self.context, None, rect, color, color_srgb, depth, stencil);
1290 }
1291
1292 fn get_dimensions(&self) -> (u32, u32) {
1293 self.dimensions
1294 }
1295
1296 fn get_depth_buffer_bits(&self) -> Option<u16> {
1297 self.context.capabilities().depth_bits
1298 }
1299
1300 fn get_stencil_buffer_bits(&self) -> Option<u16> {
1301 self.context.capabilities().stencil_bits
1302 }
1303
1304 fn draw<'a, 'b, V, I, U>(&mut self, vertex_buffer: V,
1305 index_buffer: I, program: &Program, uniforms: &U,
1306 draw_parameters: &DrawParameters<'_>) -> Result<(), DrawError>
1307 where I: Into<index::IndicesSource<'a>>, U: uniforms::Uniforms,
1308 V: vertex::MultiVerticesSource<'b>
1309 {
1310 if !self.has_depth_buffer() && (draw_parameters.depth.test.requires_depth_buffer() ||
1311 draw_parameters.depth.write)
1312 {
1313 return Err(DrawError::NoDepthBuffer);
1314 }
1315
1316 if let Some(viewport) = draw_parameters.viewport {
1317 if viewport.width > self.context.capabilities().max_viewport_dims.0
1318 as u32
1319 {
1320 return Err(DrawError::ViewportTooLarge);
1321 }
1322 if viewport.height > self.context.capabilities().max_viewport_dims.1
1323 as u32
1324 {
1325 return Err(DrawError::ViewportTooLarge);
1326 }
1327 }
1328
1329 ops::draw(&self.context, None, vertex_buffer, index_buffer.into(), program,
1330 uniforms, draw_parameters, self.dimensions)
1331 }
1332
1333 #[inline]
1334 fn blit_color<S>(&self, source_rect: &Rect, target: &S, target_rect: &BlitTarget,
1335 filter: uniforms::MagnifySamplerFilter) where S: Surface
1336 {
1337 target.blit_from_frame(source_rect, target_rect, filter)
1338 }
1339
1340 fn blit_buffers_from_frame(&self, source_rect: &Rect, target_rect: &BlitTarget, filter: MagnifySamplerFilter, mask: BlitMask) {
1341 ops::blit(&self.context, None, self.get_attachments(),
1342 mask.to_glenum(), source_rect, target_rect, filter.to_glenum())
1343 }
1344
1345 fn blit_buffers_from_simple_framebuffer(&self, source: &framebuffer::SimpleFrameBuffer<'_>,
1346 source_rect: &Rect, target_rect: &BlitTarget,
1347 filter: uniforms::MagnifySamplerFilter,
1348 mask: BlitMask) {
1349 ops::blit(&self.context, source.get_attachments(), self.get_attachments(),
1350 mask.to_glenum(), source_rect, target_rect, filter.to_glenum())
1351 }
1352
1353 fn blit_buffers_from_multioutput_framebuffer(&self,
1354 source: &framebuffer::MultiOutputFrameBuffer<'_>,
1355 source_rect: &Rect, target_rect: &BlitTarget,
1356 filter: uniforms::MagnifySamplerFilter,
1357 mask: BlitMask) {
1358 ops::blit(&self.context, source.get_attachments(), self.get_attachments(),
1359 mask.to_glenum(), source_rect, target_rect, filter.to_glenum())
1360 }
1361}
1362
1363impl FboAttachments for Frame {
1364 #[inline]
1365 fn get_attachments(&self) -> Option<&fbo::ValidatedAttachments<'_>> {
1366 None
1367 }
1368}
1369
1370impl Drop for Frame {
1371 #[inline]
1372 fn drop(&mut self) {
1373 if !thread::panicking() {
1374 assert!(self.destroyed, "The `Frame` object must be explicitly destroyed \
1375 by calling `.finish()`");
1376 }
1377 }
1378}
1379
1380/// Returned during Context creation if the OpenGL implementation is too old.
1381#[derive(Clone, Debug, PartialEq, Eq)]
1382pub struct IncompatibleOpenGl(pub String);
1383
1384impl fmt::Display for IncompatibleOpenGl {
1385 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1386 fmt.write_str("The OpenGL implementation is too old to work with glium")
1387 }
1388}
1389
1390impl Error for IncompatibleOpenGl {}
1391
1392#[allow(dead_code)]
1393#[inline]
1394fn get_gl_error(ctxt: &mut context::CommandContext<'_>) -> Option<&'static str> {
1395 match unsafe { ctxt.gl.GetError() } {
1396 gl::NO_ERROR => None,
1397 gl::INVALID_ENUM => Some("GL_INVALID_ENUM"),
1398 gl::INVALID_VALUE => Some("GL_INVALID_VALUE"),
1399 gl::INVALID_OPERATION => Some("GL_INVALID_OPERATION"),
1400 gl::INVALID_FRAMEBUFFER_OPERATION => Some("GL_INVALID_FRAMEBUFFER_OPERATION"),
1401 gl::OUT_OF_MEMORY => Some("GL_OUT_OF_MEMORY"),
1402 gl::STACK_UNDERFLOW => Some("GL_STACK_UNDERFLOW"),
1403 gl::STACK_OVERFLOW => Some("GL_STACK_OVERFLOW"),
1404 gl::CONTEXT_LOST => Some("GL_CONTEXT_LOST"),
1405 _ => Some("Unknown glGetError return value")
1406 }
1407}
1408