diff options
Diffstat (limited to 'opengl-bindings/src/misc.rs')
| -rw-r--r-- | opengl-bindings/src/misc.rs | 190 | 
1 files changed, 190 insertions, 0 deletions
diff --git a/opengl-bindings/src/misc.rs b/opengl-bindings/src/misc.rs new file mode 100644 index 0000000..bb54c1a --- /dev/null +++ b/opengl-bindings/src/misc.rs @@ -0,0 +1,190 @@ +use bitflags::bitflags; + +use crate::data_types::{Dimens, Vec2}; +use crate::CurrentContextWithFns; + +/// Sets the viewport. +/// +/// The `u32` values in `position` and `size` must fit in `i32`s. +/// +/// # Errors +/// Returns `Err` if any value in `position` or `size` does not fit into a `i32`. +pub fn set_viewport( +    current_context: &CurrentContextWithFns<'_>, +    position: &Vec2<u32>, +    size: &Dimens<u32>, +) -> Result<(), SetViewportError> +{ +    let position = Vec2::<crate::sys::types::GLint> { +        x: position.x.try_into().map_err(|_| { +            SetViewportError::PositionXValueTooLarge { +                value: position.x, +                max_value: crate::sys::types::GLint::MAX as u32, +            } +        })?, +        y: position.y.try_into().map_err(|_| { +            SetViewportError::PositionYValueTooLarge { +                value: position.y, +                max_value: crate::sys::types::GLint::MAX as u32, +            } +        })?, +    }; + +    let size = Dimens::<crate::sys::types::GLsizei> { +        width: size.width.try_into().map_err(|_| { +            SetViewportError::SizeWidthValueTooLarge { +                value: size.width, +                max_value: crate::sys::types::GLsizei::MAX as u32, +            } +        })?, +        height: size.height.try_into().map_err(|_| { +            SetViewportError::SizeHeightValueTooLarge { +                value: size.height, +                max_value: crate::sys::types::GLsizei::MAX as u32, +            } +        })?, +    }; + +    unsafe { +        current_context +            .fns() +            .Viewport(position.x, position.y, size.width, size.height); +    } + +    Ok(()) +} + +pub fn clear_buffers(current_context: &CurrentContextWithFns<'_>, mask: BufferClearMask) +{ +    unsafe { +        current_context.fns().Clear(mask.bits()); +    } +} + +pub fn set_polygon_mode( +    current_context: &CurrentContextWithFns<'_>, +    face: impl Into<PolygonModeFace>, +    mode: impl Into<PolygonMode>, +) +{ +    unsafe { +        current_context +            .fns() +            .PolygonMode(face.into() as u32, mode.into() as u32); +    } +} + +pub fn enable(current_context: &CurrentContextWithFns<'_>, capacity: Capability) +{ +    unsafe { +        current_context.fns().Enable(capacity as u32); +    } +} + +pub fn disable(current_context: &CurrentContextWithFns<'_>, capability: Capability) +{ +    unsafe { +        current_context.fns().Disable(capability as u32); +    } +} + +pub fn set_enabled( +    current_context: &CurrentContextWithFns<'_>, +    capability: Capability, +    enabled: bool, +) +{ +    if enabled { +        enable(current_context, capability); +    } else { +        disable(current_context, capability); +    } +} + +#[must_use] +pub fn get_context_flags(current_context: &CurrentContextWithFns<'_>) -> ContextFlags +{ +    let mut context_flags = crate::sys::types::GLint::default(); + +    unsafe { +        current_context +            .fns() +            .GetIntegerv(crate::sys::CONTEXT_FLAGS, &raw mut context_flags); +    } + +    ContextFlags::from_bits_truncate(context_flags.cast_unsigned()) +} + +bitflags! { +    #[derive(Debug, Clone, Copy)] +    pub struct BufferClearMask: u32 { +        const COLOR = crate::sys::COLOR_BUFFER_BIT; +        const DEPTH = crate::sys::DEPTH_BUFFER_BIT; +        const STENCIL = crate::sys::STENCIL_BUFFER_BIT; +    } +} + +#[derive(Debug)] +#[repr(u32)] +pub enum Capability +{ +    DepthTest = crate::sys::DEPTH_TEST, +    MultiSample = crate::sys::MULTISAMPLE, +    DebugOutput = crate::sys::DEBUG_OUTPUT, +    DebugOutputSynchronous = crate::sys::DEBUG_OUTPUT_SYNCHRONOUS, +} + +#[derive(Debug)] +#[repr(u32)] +pub enum PolygonMode +{ +    Point = crate::sys::POINT, +    Line = crate::sys::LINE, +    Fill = crate::sys::FILL, +} + +#[derive(Debug)] +#[repr(u32)] +pub enum PolygonModeFace +{ +    Front = crate::sys::FRONT, +    Back = crate::sys::BACK, +    FrontAndBack = crate::sys::FRONT_AND_BACK, +} + +bitflags! { +#[derive(Debug, Clone, Copy)] +pub struct ContextFlags: u32 { +    const FORWARD_COMPATIBLE = crate::sys::CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT; +    const DEBUG = crate::sys::CONTEXT_FLAG_DEBUG_BIT; +    const ROBUST_ACCESS = crate::sys::CONTEXT_FLAG_ROBUST_ACCESS_BIT; +} +} + +#[derive(Debug, thiserror::Error)] +pub enum SetViewportError +{ +    #[error("Position X value ({value}) is too large. Must be < {max_value}")] +    PositionXValueTooLarge +    { +        value: u32, max_value: u32 +    }, + +    #[error("Position Y value ({value}) is too large. Must be < {max_value}")] +    PositionYValueTooLarge +    { +        value: u32, max_value: u32 +    }, + +    #[error("Size width value ({value}) is too large. Must be < {max_value}")] +    SizeWidthValueTooLarge +    { +        value: u32, max_value: u32 +    }, + +    #[error("Size height value ({value}) is too large. Must be < {max_value}")] +    SizeHeightValueTooLarge +    { +        value: u32, max_value: u32 +    }, +}  | 
