diff options
author | HampusM <hampus@hampusmat.com> | 2025-09-19 16:36:57 +0200 |
---|---|---|
committer | HampusM <hampus@hampusmat.com> | 2025-10-02 16:55:33 +0200 |
commit | ea1d70c8c28e3b96da6264021fa1c62e28fcd8e4 (patch) | |
tree | 62ae9b75ee84602899b51483ed26fa664df36888 /opengl-bindings/src/misc.rs | |
parent | 0008b374c7f3a9ef6b30ea31a4a8c98bce64649f (diff) |
feat: add OpenGL bindings crate
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 + }, +} |