1use std::rc::Rc;
75use smallvec::SmallVec;
76
77use crate::texture::TextureAnyImage;
78
79use crate::backend::Facade;
80use crate::context::Context;
81use crate::{CapabilitiesSource, BlitMask};
82use crate::version::Version;
83use crate::version::Api;
84
85use crate::FboAttachments;
86use crate::Rect;
87use crate::BlitTarget;
88use crate::ContextExt;
89use crate::ToGlEnum;
90use crate::ops;
91use crate::uniforms;
92
93use crate::{Program, Surface};
94use crate::DrawError;
95
96use crate::fbo;
97
98pub use self::default_fb::{DefaultFramebufferAttachment, DefaultFramebuffer};
99pub use self::render_buffer::{RenderBuffer, RenderBufferAny, DepthRenderBuffer};
100pub use self::render_buffer::{StencilRenderBuffer, DepthStencilRenderBuffer};
101pub use self::render_buffer::CreationError as RenderBufferCreationError;
102pub use crate::fbo::is_dimensions_mismatch_supported;
103pub use crate::fbo::ValidationError;
104use crate::uniforms::MagnifySamplerFilter;
105
106mod default_fb;
107mod render_buffer;
108
109pub struct SimpleFrameBuffer<'a> {
111 context: Rc<Context>,
112 attachments: fbo::ValidatedAttachments<'a>,
113}
114
115impl<'a> SimpleFrameBuffer<'a> {
116 #[inline]
119 pub fn new<F: ?Sized, C>(facade: &F, color: C) -> Result<SimpleFrameBuffer<'a>, ValidationError>
120 where C: ToColorAttachment<'a>, F: Facade
121 {
122 SimpleFrameBuffer::new_impl(facade, Some(color.to_color_attachment()), None, None, None)
123 }
124
125 #[inline]
128 pub fn with_depth_buffer<F: ?Sized, C, D>(facade: &F, color: C, depth: D)
129 -> Result<SimpleFrameBuffer<'a>, ValidationError>
130 where C: ToColorAttachment<'a>,
131 D: ToDepthAttachment<'a>, F: Facade
132 {
133 SimpleFrameBuffer::new_impl(facade, Some(color.to_color_attachment()),
134 Some(depth.to_depth_attachment()), None, None)
135 }
136
137 #[inline]
140 pub fn depth_only<F: ?Sized, D>(facade: &F, depth: D)
141 -> Result<SimpleFrameBuffer<'a>, ValidationError>
142 where D: ToDepthAttachment<'a>, F: Facade
143 {
144 SimpleFrameBuffer::new_impl(facade, None, Some(depth.to_depth_attachment()), None, None)
145 }
146
147 #[inline]
150 pub fn with_depth_and_stencil_buffer<F: ?Sized, C, D, S>(facade: &F, color: C, depth: D,
151 stencil: S)
152 -> Result<SimpleFrameBuffer<'a>,
153 ValidationError>
154 where C: ToColorAttachment<'a>,
155 D: ToDepthAttachment<'a>,
156 S: ToStencilAttachment<'a>, F: Facade
157 {
158 SimpleFrameBuffer::new_impl(facade, Some(color.to_color_attachment()),
159 Some(depth.to_depth_attachment()),
160 Some(stencil.to_stencil_attachment()), None)
161 }
162
163 #[inline]
166 pub fn depth_and_stencil_only<F: ?Sized, D, S>(facade: &F, depth: D, stencil: S)
167 -> Result<SimpleFrameBuffer<'a>, ValidationError>
168 where D: ToDepthAttachment<'a>,
169 S: ToStencilAttachment<'a>, F: Facade
170 {
171 SimpleFrameBuffer::new_impl(facade, None, Some(depth.to_depth_attachment()),
172 Some(stencil.to_stencil_attachment()), None)
173 }
174
175 #[inline]
178 pub fn with_stencil_buffer<F: ?Sized, C, S>(facade: &F, color: C, stencil: S)
179 -> Result<SimpleFrameBuffer<'a>, ValidationError>
180 where C: ToColorAttachment<'a>, S: ToStencilAttachment<'a>,
181 F: Facade
182 {
183 SimpleFrameBuffer::new_impl(facade, Some(color.to_color_attachment()), None,
184 Some(stencil.to_stencil_attachment()), None)
185 }
186
187 #[inline]
190 pub fn stencil_only<F: ?Sized, S>(facade: &F, stencil: S)
191 -> Result<SimpleFrameBuffer<'a>, ValidationError>
192 where S: ToStencilAttachment<'a>, F: Facade
193 {
194 SimpleFrameBuffer::new_impl(facade, None, None, Some(stencil.to_stencil_attachment()),
195 None)
196 }
197
198 #[inline]
200 pub fn with_depth_stencil_buffer<F: ?Sized, C, D>(facade: &F, color: C, depthstencil: D)
201 -> Result<SimpleFrameBuffer<'a>, ValidationError>
202 where C: ToColorAttachment<'a>,
203 D: ToDepthStencilAttachment<'a>, F: Facade
204 {
205 SimpleFrameBuffer::new_impl(facade, Some(color.to_color_attachment()), None, None,
206 Some(depthstencil.to_depth_stencil_attachment()))
207 }
208
209 #[inline]
211 pub fn depth_stencil_only<F: ?Sized, D>(facade: &F, depthstencil: D)
212 -> Result<SimpleFrameBuffer<'a>, ValidationError>
213 where D: ToDepthStencilAttachment<'a>, F: Facade
214 {
215 SimpleFrameBuffer::new_impl(facade, None, None, None,
216 Some(depthstencil.to_depth_stencil_attachment()))
217 }
218
219
220 fn new_impl<F: ?Sized>(facade: &F, color: Option<ColorAttachment<'a>>,
221 depth: Option<DepthAttachment<'a>>, stencil: Option<StencilAttachment<'a>>,
222 depthstencil: Option<DepthStencilAttachment<'a>>)
223 -> Result<SimpleFrameBuffer<'a>, ValidationError> where F: Facade
224 {
225 let color = color.map(|color| match color {
226 ColorAttachment::Texture(tex) => fbo::RegularAttachment::Texture(tex),
227 ColorAttachment::RenderBuffer(buffer) => fbo::RegularAttachment::RenderBuffer(buffer),
228 });
229
230 let depth = depth.map(|depth| match depth {
231 DepthAttachment::Texture(tex) => fbo::RegularAttachment::Texture(tex),
232 DepthAttachment::RenderBuffer(buffer) => fbo::RegularAttachment::RenderBuffer(buffer),
233 });
234
235 let stencil = stencil.map(|stencil| match stencil {
236 StencilAttachment::Texture(tex) => fbo::RegularAttachment::Texture(tex),
237 StencilAttachment::RenderBuffer(buffer) => fbo::RegularAttachment::RenderBuffer(buffer),
238 });
239
240 let depthstencil = depthstencil.map(|depthstencil| match depthstencil {
241 DepthStencilAttachment::Texture(tex) => fbo::RegularAttachment::Texture(tex),
242 DepthStencilAttachment::RenderBuffer(buffer) => fbo::RegularAttachment::RenderBuffer(buffer),
243 });
244
245 let attachments = fbo::FramebufferAttachments::Regular(fbo::FramebufferSpecificAttachments {
246 colors: if let Some(color) = color {
247 let mut v = SmallVec::new(); v.push((0, color)); v
248 } else {
249 SmallVec::new()
250 },
251 depth_stencil: if let (Some(depth), Some(stencil)) = (depth, stencil) {
252 fbo::DepthStencilAttachments::DepthAndStencilAttachments(depth, stencil)
253 } else if let Some(depth) = depth {
254 fbo::DepthStencilAttachments::DepthAttachment(depth)
255 } else if let Some(stencil) = stencil {
256 fbo::DepthStencilAttachments::StencilAttachment(stencil)
257 } else if let Some(depthstencil) = depthstencil {
258 fbo::DepthStencilAttachments::DepthStencilAttachment(depthstencil)
259 } else {
260 fbo::DepthStencilAttachments::None
261 }
262 });
263
264 let attachments = attachments.validate(facade)?;
265
266 Ok(SimpleFrameBuffer {
267 context: facade.get_context().clone(),
268 attachments,
269 })
270 }
271}
272
273impl<'a> Surface for SimpleFrameBuffer<'a> {
274 #[inline]
275 fn clear(&mut self, rect: Option<&Rect>, color: Option<(f32, f32, f32, f32)>, color_srgb: bool,
276 depth: Option<f32>, stencil: Option<i32>)
277 {
278 ops::clear(&self.context, Some(&self.attachments), rect, color, color_srgb, depth, stencil);
279 }
280
281 #[inline]
282 fn get_dimensions(&self) -> (u32, u32) {
283 self.attachments.get_dimensions()
284 }
285
286 #[inline]
287 fn get_depth_buffer_bits(&self) -> Option<u16> {
288 self.attachments.get_depth_buffer_bits()
289 }
290
291 #[inline]
292 fn get_stencil_buffer_bits(&self) -> Option<u16> {
293 self.attachments.get_stencil_buffer_bits()
294 }
295
296 fn draw<'b, 'v, V, I, U>(&mut self, vb: V, ib: I, program: &crate::Program,
297 uniforms: &U, draw_parameters: &crate::DrawParameters<'_>) -> Result<(), DrawError>
298 where I: Into<crate::index::IndicesSource<'b>>, U: crate::uniforms::Uniforms,
299 V: crate::vertex::MultiVerticesSource<'v>
300 {
301 if !self.has_depth_buffer() && (draw_parameters.depth.test.requires_depth_buffer() ||
302 draw_parameters.depth.write)
303 {
304 return Err(DrawError::NoDepthBuffer);
305 }
306
307 if let Some(viewport) = draw_parameters.viewport {
308 if viewport.width > self.context.capabilities().max_viewport_dims.0
309 as u32
310 {
311 return Err(DrawError::ViewportTooLarge);
312 }
313 if viewport.height > self.context.capabilities().max_viewport_dims.1
314 as u32
315 {
316 return Err(DrawError::ViewportTooLarge);
317 }
318 }
319
320 ops::draw(&self.context, Some(&self.attachments), vb,
321 ib.into(), program, uniforms, draw_parameters, self.get_dimensions())
322 }
323
324 #[inline]
325 fn blit_color<S>(&self, source_rect: &Rect, target: &S, target_rect: &BlitTarget,
326 filter: uniforms::MagnifySamplerFilter) where S: Surface
327 {
328 target.blit_from_simple_framebuffer(self, source_rect, target_rect, filter)
329 }
330
331 #[inline]
332 fn blit_buffers_from_frame(&self, source_rect: &Rect, target_rect: &BlitTarget, filter: MagnifySamplerFilter, mask: BlitMask) {
333 ops::blit(&self.context, None, self.get_attachments(),
334 mask.to_glenum(), source_rect, target_rect, filter.to_glenum())
335 }
336
337 #[inline]
338 fn blit_buffers_from_simple_framebuffer(&self, source: &SimpleFrameBuffer<'_>, source_rect: &Rect, target_rect: &BlitTarget, filter: MagnifySamplerFilter, mask: BlitMask) {
339 ops::blit(&self.context, source.get_attachments(), self.get_attachments(),
340 mask.to_glenum(), source_rect, target_rect, filter.to_glenum())
341 }
342
343 #[inline]
344 fn blit_buffers_from_multioutput_framebuffer(&self, source: &MultiOutputFrameBuffer<'_>, source_rect: &Rect, target_rect: &BlitTarget, filter: MagnifySamplerFilter, mask: BlitMask) {
345 ops::blit(&self.context, source.get_attachments(), self.get_attachments(),
346 mask.to_glenum(), source_rect, target_rect, filter.to_glenum())
347 }
348}
349
350impl<'a> FboAttachments for SimpleFrameBuffer<'a> {
351 #[inline]
352 fn get_attachments(&self) -> Option<&fbo::ValidatedAttachments<'_>> {
353 Some(&self.attachments)
354 }
355}
356
357pub struct MultiOutputFrameBuffer<'a> {
359 context: Rc<Context>,
360 example_attachments: fbo::ValidatedAttachments<'a>,
361 color_attachments: Vec<(String, fbo::RegularAttachment<'a>)>,
362 depth_stencil_attachments: fbo::DepthStencilAttachments<fbo::RegularAttachment<'a>>,
363}
364
365impl<'a> MultiOutputFrameBuffer<'a> {
366 #[inline]
372 pub fn new<F: ?Sized, I, A>(facade: &F, color_attachments: I)
373 -> Result<MultiOutputFrameBuffer<'a>, ValidationError>
374 where F: Facade,
375 I: IntoIterator<Item = (&'a str, A)>,
376 A: ToColorAttachment<'a>,
377 {
378 MultiOutputFrameBuffer::new_impl(facade, color_attachments, None, None, None)
379 }
380
381 #[inline]
387 pub fn with_depth_buffer<F: ?Sized, D, I, A>(facade: &F, color_attachments: I, depth: D)
388 -> Result<MultiOutputFrameBuffer<'a>, ValidationError>
389 where F: Facade,
390 D: ToDepthAttachment<'a>,
391 I: IntoIterator<Item = (&'a str, A)>,
392 A: ToColorAttachment<'a>,
393 {
394 MultiOutputFrameBuffer::new_impl(facade, color_attachments,
395 Some(depth.to_depth_attachment()), None, None)
396 }
397
398 #[inline]
404 pub fn with_depth_and_stencil_buffer<A, F: ?Sized, I, D, S>(facade: &F, color: I, depth: D, stencil: S)
405 -> Result<MultiOutputFrameBuffer<'a>,
406 ValidationError>
407 where D: ToDepthAttachment<'a>,
408 I: IntoIterator<Item = (&'a str, A)>,
409 S: ToStencilAttachment<'a>,
410 A: ToColorAttachment<'a>,
411 F: Facade
412 {
413 MultiOutputFrameBuffer::new_impl(facade, color,
414 Some(depth.to_depth_attachment()),
415 Some(stencil.to_stencil_attachment()), None)
416 }
417
418 #[inline]
424 pub fn with_stencil_buffer<A, F: ?Sized, I, S>(facade: &F, color: I, stencil: S)
425 -> Result<MultiOutputFrameBuffer<'a>, ValidationError>
426 where S: ToStencilAttachment<'a>,
427 F: Facade,
428 I: IntoIterator<Item = (&'a str, A)>,
429 A: ToColorAttachment<'a>,
430 {
431 MultiOutputFrameBuffer::new_impl(facade, color, None,
432 Some(stencil.to_stencil_attachment()), None)
433 }
434
435 #[inline]
441 pub fn with_depth_stencil_buffer<A, F: ?Sized, I, D>(facade: &F, color: I, depthstencil: D)
442 -> Result<MultiOutputFrameBuffer<'a>, ValidationError>
443 where D: ToDepthStencilAttachment<'a>, F: Facade,
444 I: IntoIterator<Item = (&'a str, A)>,
445 A: ToColorAttachment<'a>,
446 {
447 MultiOutputFrameBuffer::new_impl(facade, color, None, None,
448 Some(depthstencil.to_depth_stencil_attachment()))
449 }
450
451 fn new_impl<F: ?Sized, I, A>(facade: &F, color: I, depth: Option<DepthAttachment<'a>>,
452 stencil: Option<StencilAttachment<'a>>,
453 depthstencil: Option<DepthStencilAttachment<'a>>)
454 -> Result<MultiOutputFrameBuffer<'a>, ValidationError>
455 where F: Facade,
456 I: IntoIterator<Item = (&'a str, A)>,
457 A: ToColorAttachment<'a>,
458 {
459 let color = color.into_iter().map(|(name, tex)| {
460 let atch = tex.to_color_attachment();
461 let atch = if let ColorAttachment::Texture(t) = atch { t } else { panic!() };
462 (name.to_owned(), fbo::RegularAttachment::Texture(atch))
463 }).collect::<Vec<_>>();
464
465 let example_color = {
466 let mut v = SmallVec::new();
467 for e in color.iter().enumerate().map(|(index, &(_, tex))| { (index as u32, tex) }) {
468 v.push(e);
469 }
470 v
471 };
472
473 let depth = depth.map(|depth| match depth {
474 DepthAttachment::Texture(tex) => fbo::RegularAttachment::Texture(tex),
475 DepthAttachment::RenderBuffer(buffer) => fbo::RegularAttachment::RenderBuffer(buffer),
476 });
477
478 let stencil = stencil.map(|stencil| match stencil {
479 StencilAttachment::Texture(tex) => fbo::RegularAttachment::Texture(tex),
480 StencilAttachment::RenderBuffer(buffer) => fbo::RegularAttachment::RenderBuffer(buffer),
481 });
482
483 let depthstencil = depthstencil.map(|depthstencil| match depthstencil {
484 DepthStencilAttachment::Texture(tex) => fbo::RegularAttachment::Texture(tex),
485 DepthStencilAttachment::RenderBuffer(buffer) => fbo::RegularAttachment::RenderBuffer(buffer),
486 });
487
488 let depth_stencil_attachments = if let (Some(depth), Some(stencil)) = (depth, stencil) {
489 fbo::DepthStencilAttachments::DepthAndStencilAttachments(depth, stencil)
490 } else if let Some(depth) = depth {
491 fbo::DepthStencilAttachments::DepthAttachment(depth)
492 } else if let Some(stencil) = stencil {
493 fbo::DepthStencilAttachments::StencilAttachment(stencil)
494 } else if let Some(depthstencil) = depthstencil {
495 fbo::DepthStencilAttachments::DepthStencilAttachment(depthstencil)
496 } else {
497 fbo::DepthStencilAttachments::None
498 };
499
500 let example_attachments = fbo::FramebufferAttachments::Regular(fbo::FramebufferSpecificAttachments {
501 colors: example_color,
502 depth_stencil: depth_stencil_attachments,
503 }).validate(facade)?;
504
505 Ok(MultiOutputFrameBuffer {
506 context: facade.get_context().clone(),
507 example_attachments,
508 color_attachments: color,
509 depth_stencil_attachments,
510 })
511 }
512
513 fn build_attachments(&self, program: &Program) -> fbo::ValidatedAttachments<'_> {
514 let mut colors = SmallVec::new();
515
516 for &(ref name, attachment) in self.color_attachments.iter() {
517 let location = match program.get_frag_data_location(&name) {
518 Some(l) => l,
519 None => panic!("The fragment output `{}` was not found in the program", name)
520 };
521
522 colors.push((location, attachment));
523 }
524
525 fbo::FramebufferAttachments::Regular(fbo::FramebufferSpecificAttachments {
526 colors,
527 depth_stencil: self.depth_stencil_attachments,
528 }).validate(&self.context).unwrap()
529 }
530}
531
532impl<'a> Surface for MultiOutputFrameBuffer<'a> {
533 #[inline]
534 fn clear(&mut self, rect: Option<&Rect>, color: Option<(f32, f32, f32, f32)>, color_srgb: bool,
535 depth: Option<f32>, stencil: Option<i32>)
536 {
537 ops::clear(&self.context, Some(&self.example_attachments), rect,
538 color, color_srgb, depth, stencil);
539 }
540
541 #[inline]
542 fn get_dimensions(&self) -> (u32, u32) {
543 self.example_attachments.get_dimensions()
544 }
545
546 #[inline]
547 fn get_depth_buffer_bits(&self) -> Option<u16> {
548 self.example_attachments.get_depth_buffer_bits()
549 }
550
551 #[inline]
552 fn get_stencil_buffer_bits(&self) -> Option<u16> {
553 self.example_attachments.get_stencil_buffer_bits()
554 }
555
556 fn draw<'i, 'v, V, I, U>(&mut self, vb: V, ib: I, program: &crate::Program,
557 uniforms: &U, draw_parameters: &crate::DrawParameters<'_>) -> Result<(), DrawError>
558 where I: Into<crate::index::IndicesSource<'i>>,
559 U: crate::uniforms::Uniforms, V: crate::vertex::MultiVerticesSource<'v>
560 {
561 if !self.has_depth_buffer() && (draw_parameters.depth.test.requires_depth_buffer() ||
562 draw_parameters.depth.write)
563 {
564 return Err(DrawError::NoDepthBuffer);
565 }
566
567 if let Some(viewport) = draw_parameters.viewport {
568 if viewport.width > self.context.capabilities().max_viewport_dims.0
569 as u32
570 {
571 return Err(DrawError::ViewportTooLarge);
572 }
573 if viewport.height > self.context.capabilities().max_viewport_dims.1
574 as u32
575 {
576 return Err(DrawError::ViewportTooLarge);
577 }
578 }
579
580 ops::draw(&self.context, Some(&self.build_attachments(program)), vb,
581 ib.into(), program, uniforms, draw_parameters, self.get_dimensions())
582 }
583
584 #[inline]
585 fn blit_color<S>(&self, source_rect: &Rect, target: &S, target_rect: &BlitTarget,
586 filter: uniforms::MagnifySamplerFilter) where S: Surface
587 {
588 target.blit_from_multioutput_framebuffer(self, source_rect, target_rect, filter)
589 }
590
591 #[inline]
592 fn blit_buffers_from_frame(&self, source_rect: &Rect, target_rect: &BlitTarget, filter: MagnifySamplerFilter, mask: BlitMask) {
593 ops::blit(&self.context, None, self.get_attachments(),
594 mask.to_glenum(), source_rect, target_rect, filter.to_glenum())
595 }
596
597 #[inline]
598 fn blit_buffers_from_simple_framebuffer(&self, source: &SimpleFrameBuffer<'_>, source_rect: &Rect, target_rect: &BlitTarget, filter: MagnifySamplerFilter, mask: BlitMask) {
599 ops::blit(&self.context, source.get_attachments(), self.get_attachments(),
600 mask.to_glenum(), source_rect, target_rect, filter.to_glenum())
601 }
602
603 #[inline]
604 fn blit_buffers_from_multioutput_framebuffer(&self, source: &MultiOutputFrameBuffer<'_>, source_rect: &Rect, target_rect: &BlitTarget, filter: MagnifySamplerFilter, mask: BlitMask) {
605 ops::blit(&self.context, source.get_attachments(), self.get_attachments(),
606 mask.to_glenum(), source_rect, target_rect, filter.to_glenum())
607 }
608}
609
610impl<'a> FboAttachments for MultiOutputFrameBuffer<'a> {
611 #[inline]
612 fn get_attachments(&self) -> Option<&fbo::ValidatedAttachments<'_>> {
613 unimplemented!();
614 }
615}
616
617pub struct EmptyFrameBuffer {
621 context: Rc<Context>,
622 attachments: fbo::ValidatedAttachments<'static>,
623}
624
625impl<'a> EmptyFrameBuffer {
626 pub fn is_supported<C: ?Sized>(context: &C) -> bool where C: CapabilitiesSource {
628 context.get_version() >= &Version(Api::Gl, 4, 3) ||
629 context.get_version() >= &Version(Api::GlEs, 3, 1) ||
630 context.get_extensions().gl_arb_framebuffer_no_attachments
631 }
632
633 pub fn is_layered_supported<C: ?Sized>(context: &C) -> bool where C: CapabilitiesSource {
635 context.get_version() >= &Version(Api::Gl, 4, 3) ||
636 context.get_version() >= &Version(Api::GlEs, 3, 2) ||
637 context.get_extensions().gl_arb_framebuffer_no_attachments
638 }
639
640 pub fn get_max_supported_width<C: ?Sized>(context: &C) -> Option<u32> where C: CapabilitiesSource {
643 context.get_capabilities().max_framebuffer_width.map(|v| v as u32)
644 }
645
646 pub fn get_max_supported_height<C: ?Sized>(context: &C) -> Option<u32> where C: CapabilitiesSource {
649 context.get_capabilities().max_framebuffer_height.map(|v| v as u32)
650 }
651
652 pub fn get_max_supported_samples<C: ?Sized>(context: &C) -> Option<u32> where C: CapabilitiesSource {
655 context.get_capabilities().max_framebuffer_samples.map(|v| v as u32)
656 }
657
658 pub fn get_max_supported_layers<C: ?Sized>(context: &C) -> Option<u32> where C: CapabilitiesSource {
661 context.get_capabilities().max_framebuffer_layers.map(|v| v as u32)
662 }
663
664 #[inline]
671 pub fn new<F: ?Sized>(facade: &F, width: u32, height: u32, layers: Option<u32>,
672 samples: Option<u32>, fixed_samples: bool)
673 -> Result<EmptyFrameBuffer, ValidationError> where F: Facade
674 {
675 let context = facade.get_context();
676
677 let attachments = fbo::FramebufferAttachments::Empty {
678 width,
679 height,
680 layers,
681 samples,
682 fixed_samples,
683 };
684
685 let attachments = attachments.validate(context)?;
686
687 Ok(EmptyFrameBuffer {
688 context: context.clone(),
689 attachments,
690 })
691 }
692}
693
694impl Surface for EmptyFrameBuffer {
695 #[inline]
696 fn clear(&mut self, rect: Option<&Rect>, color: Option<(f32, f32, f32, f32)>, color_srgb: bool,
697 depth: Option<f32>, stencil: Option<i32>)
698 {
699 ops::clear(&self.context, Some(&self.attachments), rect, color, color_srgb, depth, stencil);
700 }
701
702 #[inline]
703 fn get_dimensions(&self) -> (u32, u32) {
704 self.attachments.get_dimensions()
705 }
706
707 #[inline]
708 fn get_depth_buffer_bits(&self) -> Option<u16> {
709 None
710 }
711
712 #[inline]
713 fn get_stencil_buffer_bits(&self) -> Option<u16> {
714 None
715 }
716
717 fn draw<'b, 'v, V, I, U>(&mut self, vb: V, ib: I, program: &crate::Program,
718 uniforms: &U, draw_parameters: &crate::DrawParameters<'_>) -> Result<(), DrawError>
719 where I: Into<crate::index::IndicesSource<'b>>, U: crate::uniforms::Uniforms,
720 V: crate::vertex::MultiVerticesSource<'v>
721 {
722 if !self.has_depth_buffer() && (draw_parameters.depth.test.requires_depth_buffer() ||
723 draw_parameters.depth.write)
724 {
725 return Err(DrawError::NoDepthBuffer);
726 }
727
728 if let Some(viewport) = draw_parameters.viewport {
729 if viewport.width > self.context.capabilities().max_viewport_dims.0
730 as u32
731 {
732 return Err(DrawError::ViewportTooLarge);
733 }
734 if viewport.height > self.context.capabilities().max_viewport_dims.1
735 as u32
736 {
737 return Err(DrawError::ViewportTooLarge);
738 }
739 }
740
741 ops::draw(&self.context, Some(&self.attachments), vb,
742 ib.into(), program, uniforms, draw_parameters, self.get_dimensions())
743 }
744
745 #[inline]
746 fn blit_color<S>(&self, source_rect: &Rect, target: &S, target_rect: &BlitTarget,
747 filter: uniforms::MagnifySamplerFilter) where S: Surface
748 {
749 unimplemented!() }
751
752 #[inline]
753 fn blit_buffers_from_frame(&self, source_rect: &Rect, target_rect: &BlitTarget,
754 filter: uniforms::MagnifySamplerFilter, mask: BlitMask)
755 {
756 ops::blit(&self.context, None, self.get_attachments(),
757 mask.to_glenum(), source_rect, target_rect, filter.to_glenum())
758 }
759
760 #[inline]
761 fn blit_buffers_from_simple_framebuffer(&self, source: &SimpleFrameBuffer<'_>,
762 source_rect: &Rect, target_rect: &BlitTarget,
763 filter: uniforms::MagnifySamplerFilter, mask: BlitMask)
764 {
765 ops::blit(&self.context, source.get_attachments(), self.get_attachments(),
766 mask.to_glenum(), source_rect, target_rect, filter.to_glenum())
767 }
768
769 #[inline]
770 fn blit_buffers_from_multioutput_framebuffer(&self, source: &MultiOutputFrameBuffer<'_>,
771 source_rect: &Rect, target_rect: &BlitTarget,
772 filter: uniforms::MagnifySamplerFilter,
773 mask: BlitMask)
774 {
775 ops::blit(&self.context, source.get_attachments(), self.get_attachments(),
776 mask.to_glenum(), source_rect, target_rect, filter.to_glenum())
777 }
778}
779
780impl FboAttachments for EmptyFrameBuffer {
781 #[inline]
782 fn get_attachments(&self) -> Option<&fbo::ValidatedAttachments<'_>> {
783 Some(&self.attachments)
784 }
785}
786
787#[derive(Copy, Clone)]
789pub enum ColorAttachment<'a> {
790 Texture(TextureAnyImage<'a>),
792 RenderBuffer(&'a RenderBuffer),
794}
795
796pub trait ToColorAttachment<'a> {
798 fn to_color_attachment(self) -> ColorAttachment<'a>;
800}
801
802impl<'a> ToColorAttachment<'a> for ColorAttachment<'a> {
803 #[inline]
804 fn to_color_attachment(self) -> ColorAttachment<'a> {
805 self
806 }
807}
808
809#[derive(Copy, Clone)]
811pub enum DepthAttachment<'a> {
812 Texture(TextureAnyImage<'a>),
814 RenderBuffer(&'a DepthRenderBuffer),
816}
817
818pub trait ToDepthAttachment<'a> {
820 fn to_depth_attachment(self) -> DepthAttachment<'a>;
822}
823
824impl<'a> ToDepthAttachment<'a> for DepthAttachment<'a> {
825 #[inline]
826 fn to_depth_attachment(self) -> DepthAttachment<'a> {
827 self
828 }
829}
830
831#[derive(Copy, Clone)]
833pub enum StencilAttachment<'a> {
834 Texture(TextureAnyImage<'a>),
836 RenderBuffer(&'a StencilRenderBuffer),
838}
839
840pub trait ToStencilAttachment<'a> {
842 fn to_stencil_attachment(self) -> StencilAttachment<'a>;
844}
845
846impl<'a> ToStencilAttachment<'a> for StencilAttachment<'a> {
847 #[inline]
848 fn to_stencil_attachment(self) -> StencilAttachment<'a> {
849 self
850 }
851}
852
853#[derive(Copy, Clone)]
855pub enum DepthStencilAttachment<'a> {
856 Texture(TextureAnyImage<'a>),
858 RenderBuffer(&'a DepthStencilRenderBuffer),
860}
861
862pub trait ToDepthStencilAttachment<'a> {
864 fn to_depth_stencil_attachment(self) -> DepthStencilAttachment<'a>;
866}
867
868impl<'a> ToDepthStencilAttachment<'a> for DepthStencilAttachment<'a> {
869 #[inline]
870 fn to_depth_stencil_attachment(self) -> DepthStencilAttachment<'a> {
871 self
872 }
873}