use super::*;
use super::errors::*;
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct FramebufferId(u32);
pub const DEFAULT_FRAMEBUFFER_ID: FramebufferId = FramebufferId(0);
impl From<FramebufferId> for u32 {
fn from(framebuffer_id: FramebufferId) -> Self {
framebuffer_id.0
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum FramebufferTarget {
DrawFramebuffer,
ReadFramebuffer,
Framebuffer,
}
impl From<FramebufferTarget> for gl::types::GLenum {
fn from(framebuffer_target: FramebufferTarget) -> Self {
match framebuffer_target {
FramebufferTarget::DrawFramebuffer => gl::DRAW_FRAMEBUFFER,
FramebufferTarget::ReadFramebuffer => gl::READ_FRAMEBUFFER,
FramebufferTarget::Framebuffer => gl::FRAMEBUFFER,
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum FramebufferDrawBuffer {
None,
Front,
FrontBack,
FrontLeft,
FrontRight,
Back,
BackLeft,
BackRight,
ColorAttachment0,
ColorAttachment1,
ColorAttachment2,
ColorAttachment3,
ColorAttachment4,
ColorAttachment5,
ColorAttachment6,
ColorAttachment7,
}
impl From<FramebufferDrawBuffer> for gl::types::GLenum {
fn from(framebuffer_target: FramebufferDrawBuffer) -> Self {
match framebuffer_target {
FramebufferDrawBuffer::Front => gl::FRONT,
FramebufferDrawBuffer::Back => gl::BACK,
FramebufferDrawBuffer::FrontBack => gl::FRONT_AND_BACK,
FramebufferDrawBuffer::None => gl::NONE,
FramebufferDrawBuffer::FrontLeft => gl::FRONT_LEFT,
FramebufferDrawBuffer::FrontRight => gl::FRONT_RIGHT,
FramebufferDrawBuffer::BackLeft => gl::BACK_LEFT,
FramebufferDrawBuffer::BackRight => gl::BACK_RIGHT,
FramebufferDrawBuffer::ColorAttachment0 => gl::COLOR_ATTACHMENT0,
FramebufferDrawBuffer::ColorAttachment1 => gl::COLOR_ATTACHMENT1,
FramebufferDrawBuffer::ColorAttachment2 => gl::COLOR_ATTACHMENT2,
FramebufferDrawBuffer::ColorAttachment3 => gl::COLOR_ATTACHMENT3,
FramebufferDrawBuffer::ColorAttachment4 => gl::COLOR_ATTACHMENT4,
FramebufferDrawBuffer::ColorAttachment5 => gl::COLOR_ATTACHMENT5,
FramebufferDrawBuffer::ColorAttachment6 => gl::COLOR_ATTACHMENT6,
FramebufferDrawBuffer::ColorAttachment7 => gl::COLOR_ATTACHMENT7,
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum FramebufferCompleteness {
Complete,
Undefined,
IncompleteAttachment,
IncompleteMissingAttachment,
IncompleteDrawBuffer,
IncompleteReadBuffer,
Unsupported,
IncompleteMultisample,
IncompleteLayerTargets,
Unknown,
}
impl From<FramebufferCompleteness> for gl::types::GLenum {
fn from(completeness: FramebufferCompleteness) -> Self {
match completeness {
FramebufferCompleteness::Complete => gl::FRAMEBUFFER_COMPLETE,
FramebufferCompleteness::Undefined => gl::FRAMEBUFFER_UNDEFINED,
FramebufferCompleteness::IncompleteAttachment => gl::FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
FramebufferCompleteness::IncompleteMissingAttachment => gl::FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT,
FramebufferCompleteness::IncompleteDrawBuffer => gl::FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER,
FramebufferCompleteness::IncompleteReadBuffer => gl::FRAMEBUFFER_INCOMPLETE_READ_BUFFER,
FramebufferCompleteness::Unsupported => gl::FRAMEBUFFER_UNSUPPORTED,
FramebufferCompleteness::IncompleteMultisample => gl::FRAMEBUFFER_INCOMPLETE_MULTISAMPLE,
FramebufferCompleteness::IncompleteLayerTargets => gl::FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS,
FramebufferCompleteness::Unknown => 0,
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum FramebufferAttachment {
DepthAttachment,
StencilAttachment,
DepthStencilAttachment,
ColorAttachment0,
ColorAttachment1,
ColorAttachment2,
ColorAttachment3,
ColorAttachment4,
ColorAttachment5,
ColorAttachment6,
ColorAttachment7,
}
impl From<FramebufferAttachment> for gl::types::GLenum {
fn from(framebuffer_attachment: FramebufferAttachment) -> Self {
match framebuffer_attachment {
FramebufferAttachment::DepthAttachment => gl::DEPTH_ATTACHMENT,
FramebufferAttachment::StencilAttachment => gl::STENCIL_ATTACHMENT,
FramebufferAttachment::DepthStencilAttachment => gl::DEPTH_STENCIL_ATTACHMENT,
FramebufferAttachment::ColorAttachment0 => gl::COLOR_ATTACHMENT0,
FramebufferAttachment::ColorAttachment1 => gl::COLOR_ATTACHMENT1,
FramebufferAttachment::ColorAttachment2 => gl::COLOR_ATTACHMENT2,
FramebufferAttachment::ColorAttachment3 => gl::COLOR_ATTACHMENT3,
FramebufferAttachment::ColorAttachment4 => gl::COLOR_ATTACHMENT4,
FramebufferAttachment::ColorAttachment5 => gl::COLOR_ATTACHMENT5,
FramebufferAttachment::ColorAttachment6 => gl::COLOR_ATTACHMENT6,
FramebufferAttachment::ColorAttachment7 => gl::COLOR_ATTACHMENT7,
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum ClearBuffers {
None,
Color,
Depth,
Stencil,
ColorDepth,
ColorStencil,
DepthStencil,
ColorDepthStencil,
}
impl From<ClearBuffers> for gl::types::GLenum {
fn from(buffers: ClearBuffers) -> Self {
match buffers {
ClearBuffers::None => 0,
ClearBuffers::Color => gl::COLOR_BUFFER_BIT,
ClearBuffers::Depth => gl::DEPTH_BUFFER_BIT,
ClearBuffers::Stencil => gl::STENCIL_BUFFER_BIT,
ClearBuffers::ColorDepth => gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT,
ClearBuffers::ColorStencil => gl::COLOR_BUFFER_BIT | gl::STENCIL_BUFFER_BIT,
ClearBuffers::DepthStencil => gl::DEPTH_BUFFER_BIT | gl::STENCIL_BUFFER_BIT,
ClearBuffers::ColorDepthStencil => gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT | gl::STENCIL_BUFFER_BIT,
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum FramebufferParameter {
DefaultWidth,
DefaultHeight,
DefaultLayers,
DefaultSamples,
DefaultFixedSampleLocations,
}
impl From<FramebufferParameter> for gl::types::GLenum {
fn from(parameter: FramebufferParameter) -> Self {
match parameter {
FramebufferParameter::DefaultWidth => gl::FRAMEBUFFER_DEFAULT_WIDTH,
FramebufferParameter::DefaultHeight => gl::FRAMEBUFFER_DEFAULT_HEIGHT,
FramebufferParameter::DefaultLayers => gl::FRAMEBUFFER_DEFAULT_LAYERS,
FramebufferParameter::DefaultSamples => gl::FRAMEBUFFER_DEFAULT_SAMPLES,
FramebufferParameter::DefaultFixedSampleLocations => gl::FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS,
}
}
}
pub unsafe fn clear(buffers: ClearBuffers) {
gl::Clear(buffers.into());
}
pub unsafe fn create_framebuffer() -> FramebufferId {
let mut framebuffer_id: u32 = 0;
let framebuffer_id_ptr: *mut u32 = &mut framebuffer_id;
gl::CreateFramebuffers(1, framebuffer_id_ptr);
FramebufferId(framebuffer_id)
}
pub unsafe fn delete_framebuffer(id: FramebufferId) {
gl::DeleteFramebuffers(1, &id.into());
}
pub unsafe fn bind_framebuffer(target: FramebufferTarget, framebuffer_id: FramebufferId) -> Result<()> {
gl::BindFramebuffer(target.into(), framebuffer_id.into());
get_error(())
}
pub unsafe fn named_framebuffer_draw_buffer(id: FramebufferId, buffer: FramebufferDrawBuffer) -> Result<()> {
gl::NamedFramebufferDrawBuffer(id.into(), buffer.into());
get_error(())
}
pub unsafe fn named_framebuffer_draw_buffers(id: FramebufferId, buffers: &[FramebufferDrawBuffer]) -> Result<()> {
let gl_buffers: Vec<gl::types::GLenum> = buffers.iter().map(|b| (*b).into()).collect::<_>();
let gl_buffers_ptr: *const u32 = gl_buffers.as_ptr();
gl::NamedFramebufferDrawBuffers(id.into(), buffers.len() as i32, gl_buffers_ptr);
get_error(())
}
pub unsafe fn named_framebuffer_texture(
id: FramebufferId,
attachment: FramebufferAttachment,
texture: TextureId,
level: u32,
) -> Result<()> {
gl::NamedFramebufferTexture(id.into(), attachment.into(), texture.into(), level as i32);
get_error(())
}
pub unsafe fn named_framebuffer_texture_layer(
id: FramebufferId,
attachment: FramebufferAttachment,
texture: TextureId,
level: usize,
layer: usize,
) -> Result<()> {
gl::NamedFramebufferTextureLayer(
id.into(),
attachment.into(),
texture.into(),
level as i32,
layer as i32,
);
get_error(())
}
pub unsafe fn check_named_framebuffer_status(
id: FramebufferId,
target: FramebufferTarget,
) -> Result<FramebufferCompleteness> {
let result: gl::types::GLenum = gl::CheckNamedFramebufferStatus(id.into(), target.into());
get_error(match result {
gl::FRAMEBUFFER_COMPLETE => FramebufferCompleteness::Complete,
gl::FRAMEBUFFER_UNDEFINED => FramebufferCompleteness::Undefined,
gl::FRAMEBUFFER_INCOMPLETE_ATTACHMENT => FramebufferCompleteness::IncompleteAttachment,
gl::FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT => FramebufferCompleteness::IncompleteMissingAttachment,
gl::FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER => FramebufferCompleteness::IncompleteDrawBuffer,
gl::FRAMEBUFFER_INCOMPLETE_READ_BUFFER => FramebufferCompleteness::IncompleteReadBuffer,
gl::FRAMEBUFFER_UNSUPPORTED => FramebufferCompleteness::Unsupported,
gl::FRAMEBUFFER_INCOMPLETE_MULTISAMPLE => FramebufferCompleteness::IncompleteMultisample,
gl::FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS => FramebufferCompleteness::IncompleteLayerTargets,
_ => FramebufferCompleteness::Unknown,
})
}
pub unsafe fn framebuffer_parameter(id: FramebufferId, parameter: FramebufferParameter, value: u32) -> Result<()> {
gl::NamedFramebufferParameteri(id.into(), parameter.into(), value as i32);
get_error(())
}