2022-12-01 09:21:32 +11:00
|
|
|
use crate::error::Result;
|
|
|
|
use crate::framebuffer::GLImage;
|
|
|
|
use crate::gl::FramebufferInterface;
|
|
|
|
use crate::texture::Texture;
|
2022-12-01 11:05:24 +11:00
|
|
|
use crate::viewport::Viewport;
|
2022-12-01 09:21:32 +11:00
|
|
|
use gl::types::{GLenum, GLuint};
|
|
|
|
use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
|
|
|
|
use librashader_presets::Scale2D;
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct Framebuffer {
|
2023-01-13 18:32:21 +11:00
|
|
|
pub(crate) image: GLuint,
|
|
|
|
pub(crate) handle: GLuint,
|
|
|
|
pub(crate) size: Size<u32>,
|
|
|
|
pub(crate) format: GLenum,
|
|
|
|
pub(crate) max_levels: u32,
|
|
|
|
pub(crate) mip_levels: u32,
|
|
|
|
pub(crate) is_raw: bool,
|
2022-12-01 09:21:32 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Framebuffer {
|
2023-01-13 18:32:21 +11:00
|
|
|
pub(crate) fn new<T: FramebufferInterface>(max_levels: u32) -> Self {
|
2022-12-01 09:21:32 +11:00
|
|
|
T::new(max_levels)
|
|
|
|
}
|
|
|
|
|
2023-01-13 18:32:21 +11:00
|
|
|
/// Create a framebuffer from an already initialized texture and framebuffer.
|
|
|
|
pub fn new_from_raw(
|
2022-12-01 09:21:32 +11:00
|
|
|
texture: GLuint,
|
2023-01-13 18:32:21 +11:00
|
|
|
fbo: GLuint,
|
2022-12-01 09:21:32 +11:00
|
|
|
format: GLenum,
|
|
|
|
size: Size<u32>,
|
2023-01-13 18:32:21 +11:00
|
|
|
miplevels: u32,
|
|
|
|
) -> Framebuffer {
|
|
|
|
Framebuffer {
|
|
|
|
image: texture,
|
|
|
|
size,
|
|
|
|
format,
|
|
|
|
max_levels: miplevels,
|
|
|
|
mip_levels: miplevels,
|
|
|
|
handle: fbo,
|
|
|
|
is_raw: true,
|
|
|
|
}
|
2022-12-01 09:21:32 +11:00
|
|
|
}
|
|
|
|
|
2023-01-13 18:32:21 +11:00
|
|
|
pub(crate) fn clear<T: FramebufferInterface, const REBIND: bool>(&self) {
|
2022-12-01 11:05:24 +11:00
|
|
|
T::clear::<REBIND>(self)
|
2022-12-01 09:21:32 +11:00
|
|
|
}
|
|
|
|
|
2023-01-13 18:32:21 +11:00
|
|
|
pub(crate) fn scale<T: FramebufferInterface>(
|
2022-12-01 09:21:32 +11:00
|
|
|
&mut self,
|
|
|
|
scaling: Scale2D,
|
|
|
|
format: ImageFormat,
|
|
|
|
viewport: &Viewport,
|
|
|
|
original: &Texture,
|
|
|
|
source: &Texture,
|
2023-01-13 13:29:42 +11:00
|
|
|
mipmap: bool,
|
2022-12-01 09:21:32 +11:00
|
|
|
) -> Result<Size<u32>> {
|
2023-01-12 11:09:15 +11:00
|
|
|
T::scale(self, scaling, format, viewport, original, source, mipmap)
|
2022-12-01 09:21:32 +11:00
|
|
|
}
|
|
|
|
|
2023-01-13 18:32:21 +11:00
|
|
|
pub(crate) fn copy_from<T: FramebufferInterface>(&mut self, image: &GLImage) -> Result<()> {
|
2022-12-01 09:21:32 +11:00
|
|
|
T::copy_from(self, image)
|
|
|
|
}
|
|
|
|
|
2023-01-13 18:32:21 +11:00
|
|
|
pub(crate) fn as_texture(&self, filter: FilterMode, wrap_mode: WrapMode) -> Texture {
|
2022-12-01 09:21:32 +11:00
|
|
|
Texture {
|
|
|
|
image: GLImage {
|
|
|
|
handle: self.image,
|
|
|
|
format: self.format,
|
|
|
|
size: self.size,
|
|
|
|
padded_size: Default::default(),
|
|
|
|
},
|
|
|
|
filter,
|
|
|
|
mip_filter: filter,
|
|
|
|
wrap_mode,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Drop for Framebuffer {
|
|
|
|
fn drop(&mut self) {
|
2023-01-13 18:32:21 +11:00
|
|
|
if self.is_raw {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-12-01 09:21:32 +11:00
|
|
|
unsafe {
|
|
|
|
if self.handle != 0 {
|
|
|
|
gl::DeleteFramebuffers(1, &self.handle);
|
|
|
|
}
|
|
|
|
if self.image != 0 {
|
|
|
|
gl::DeleteTextures(1, &self.image);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|