summaryrefslogtreecommitdiff
path: root/opengl-bindings/src/framebuffer.rs
diff options
context:
space:
mode:
Diffstat (limited to 'opengl-bindings/src/framebuffer.rs')
-rw-r--r--opengl-bindings/src/framebuffer.rs189
1 files changed, 189 insertions, 0 deletions
diff --git a/opengl-bindings/src/framebuffer.rs b/opengl-bindings/src/framebuffer.rs
new file mode 100644
index 0000000..9511f88
--- /dev/null
+++ b/opengl-bindings/src/framebuffer.rs
@@ -0,0 +1,189 @@
+use crate::texture::Texture;
+use crate::MaybeCurrentContextWithFns;
+
+#[derive(Debug, Clone)]
+pub struct Framebuffer
+{
+ inner: crate::sys::types::GLuint,
+}
+
+impl Framebuffer
+{
+ #[must_use]
+ pub fn new(current_context: &MaybeCurrentContextWithFns) -> Self
+ {
+ let mut inner = 0;
+
+ unsafe {
+ current_context.fns().GenFramebuffers(1, &raw mut inner);
+ }
+
+ Self { inner }
+ }
+
+ /// Attaches a texture object as a logical buffer of this framebuffer object.
+ pub fn attach_texture(
+ &self,
+ current_context: &MaybeCurrentContextWithFns,
+ attachment: Attachment,
+ texture: Texture,
+ texture_mipmap_level: u16,
+ )
+ {
+ unsafe {
+ current_context.fns().NamedFramebufferTexture(
+ self.inner,
+ attachment.into_gl(),
+ texture.into_raw(),
+ texture_mipmap_level.into(),
+ );
+ }
+ }
+
+ /// Specifies which color buffer is to be drawn into when colors are written to this
+ /// framebuffer object.
+ ///
+ /// If `buffer` is `None`, no color buffer will be written into.
+ pub fn set_draw_buffer(
+ &self,
+ current_context: &MaybeCurrentContextWithFns,
+ buffer: Option<ColorAttachment>,
+ )
+ {
+ unsafe {
+ current_context.fns().NamedFramebufferDrawBuffer(
+ self.inner,
+ buffer
+ .map(ColorAttachment::into_gl)
+ .unwrap_or(crate::sys::NONE),
+ );
+ }
+ }
+
+ pub fn delete(self, current_context: &MaybeCurrentContextWithFns)
+ {
+ unsafe {
+ current_context
+ .fns()
+ .DeleteFramebuffers(1, &raw const self.inner);
+ }
+ }
+
+ pub fn from_raw(raw: u32) -> Self
+ {
+ Self { inner: raw }
+ }
+
+ pub fn into_raw(self) -> u32
+ {
+ self.inner
+ }
+}
+
+/// Binds a framebuffer to a framebuffer target.
+///
+/// If `framebuffer` is `None`, breaks the existing binding of a framebuffer object to
+/// the framebuffer target `target`.
+pub fn bind(
+ current_context: &MaybeCurrentContextWithFns,
+ target: Target,
+ framebuffer: Option<&Framebuffer>,
+)
+{
+ unsafe {
+ current_context.fns().BindFramebuffer(
+ target.into_gl(),
+ framebuffer
+ .map(|framebuffer| framebuffer.inner)
+ .unwrap_or(0),
+ );
+ }
+}
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
+pub enum Target
+{
+ Draw,
+ Read,
+ DrawAndRead,
+}
+
+impl Target
+{
+ fn into_gl(self) -> crate::sys::types::GLenum
+ {
+ match self {
+ Self::Draw => crate::sys::DRAW_FRAMEBUFFER,
+ Self::Read => crate::sys::READ_FRAMEBUFFER,
+ Self::DrawAndRead => crate::sys::FRAMEBUFFER,
+ }
+ }
+}
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
+#[non_exhaustive]
+pub enum Attachment
+{
+ Color(ColorAttachment),
+ Depth,
+ Stencil,
+ DepthStencil,
+}
+
+impl Attachment
+{
+ fn into_gl(self) -> crate::sys::types::GLenum
+ {
+ match self {
+ Self::Color(color_attachment) => color_attachment.into_gl(),
+ Self::Depth => crate::sys::DEPTH_ATTACHMENT,
+ Self::Stencil => crate::sys::STENCIL_ATTACHMENT,
+ Self::DepthStencil => crate::sys::DEPTH_STENCIL_ATTACHMENT,
+ }
+ }
+}
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
+pub struct ColorAttachment(pub u8);
+
+impl ColorAttachment
+{
+ fn into_gl(self) -> crate::sys::types::GLenum
+ {
+ match self.0 {
+ 0 => crate::sys::COLOR_ATTACHMENT0,
+ 1 => crate::sys::COLOR_ATTACHMENT1,
+ 10 => crate::sys::COLOR_ATTACHMENT10,
+ 11 => crate::sys::COLOR_ATTACHMENT11,
+ 12 => crate::sys::COLOR_ATTACHMENT12,
+ 13 => crate::sys::COLOR_ATTACHMENT13,
+ 14 => crate::sys::COLOR_ATTACHMENT14,
+ 15 => crate::sys::COLOR_ATTACHMENT15,
+ 16 => crate::sys::COLOR_ATTACHMENT16,
+ 17 => crate::sys::COLOR_ATTACHMENT17,
+ 18 => crate::sys::COLOR_ATTACHMENT18,
+ 19 => crate::sys::COLOR_ATTACHMENT19,
+ 2 => crate::sys::COLOR_ATTACHMENT2,
+ 20 => crate::sys::COLOR_ATTACHMENT20,
+ 21 => crate::sys::COLOR_ATTACHMENT21,
+ 22 => crate::sys::COLOR_ATTACHMENT22,
+ 23 => crate::sys::COLOR_ATTACHMENT23,
+ 24 => crate::sys::COLOR_ATTACHMENT24,
+ 25 => crate::sys::COLOR_ATTACHMENT25,
+ 26 => crate::sys::COLOR_ATTACHMENT26,
+ 27 => crate::sys::COLOR_ATTACHMENT27,
+ 28 => crate::sys::COLOR_ATTACHMENT28,
+ 29 => crate::sys::COLOR_ATTACHMENT29,
+ 3 => crate::sys::COLOR_ATTACHMENT3,
+ 30 => crate::sys::COLOR_ATTACHMENT30,
+ 31 => crate::sys::COLOR_ATTACHMENT31,
+ 4 => crate::sys::COLOR_ATTACHMENT4,
+ 5 => crate::sys::COLOR_ATTACHMENT5,
+ 6 => crate::sys::COLOR_ATTACHMENT6,
+ 7 => crate::sys::COLOR_ATTACHMENT7,
+ 8 => crate::sys::COLOR_ATTACHMENT8,
+ 9 => crate::sys::COLOR_ATTACHMENT9,
+ _ => panic!("Invalid color attachment index. Must be < 32"),
+ }
+ }
+}