1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
//! Configuration of an OpenGL context.
#![allow(clippy::unnecessary_cast)]
use bitflags::bitflags;
use static_assertions::assert_not_impl_all;
use std::marker::PhantomData;
use crate::{bind, EnumInt, Result, Sdl, SdlError};
use super::GlContext;
bitflags! {
#[allow(clippy::unnecessary_cast)]
/// An attribute for OpenGL.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct GlAttributeKind: u32 {
/// The minimum bits of the red channel in a color buffer.
const RED_SIZE = bind::SDL_GL_RED_SIZE as u32;
/// The minimum bits of the gree channel in a color buffer.
const GREEN_SIZE = bind::SDL_GL_GREEN_SIZE as u32;
/// The minimum bits of the blue channel in a color buffer.
const BLUE_SIZE = bind::SDL_GL_BLUE_SIZE as u32;
/// The minimum bits of the alpha channel in a color buffer.
const ALPHA_SIZE = bind::SDL_GL_ALPHA_SIZE as u32;
/// The minimum bits of the frame buffer.
const BUFFER_SIZE = bind::SDL_GL_BUFFER_SIZE as u32;
/// Whether the output is double buffered.
const DOUBLEBUFFER = bind::SDL_GL_DOUBLEBUFFER as u32;
/// The bits of the depth buffer.
const DEPTH_SIZE = bind::SDL_GL_DEPTH_SIZE as u32;
/// The bits of the stencil buffer.
const STENCIL_SIZE = bind::SDL_GL_STENCIL_SIZE as u32;
/// The minimum bits of the red channel in an accumulation buffer.
const ACCUM_RED_SIZE = bind::SDL_GL_ACCUM_RED_SIZE as u32;
/// The minimum bits of the gree channel in an accumulation buffer.
const ACCUM_GREEN_SIZE = bind::SDL_GL_ACCUM_GREEN_SIZE as u32;
/// The minimum bits of the blue channel in an accumulation buffer.
const ACCUM_BLUE_SIZE = bind::SDL_GL_ACCUM_BLUE_SIZE as u32;
/// The minimum bits of the alpha channel in an accumulation buffer.
const ACCUM_ALPHA_SIZE = bind::SDL_GL_ACCUM_ALPHA_SIZE as u32;
/// Whether the output is stereo 3D.
const STEREO = bind::SDL_GL_STEREO as u32;
/// The number of buffers used for multi-sample anti-aliasing.
const MULTISAMPLEBUFFERS = bind::SDL_GL_MULTISAMPLEBUFFERS as u32;
/// The number of samples used for multi-sample anti-aliasing.
const MULTISAMPLESAMPLES = bind::SDL_GL_MULTISAMPLESAMPLES as u32;
/// Whether the renderer uses hardware acceleration or force software rendering.
const ACCELERATED_VISUAL = bind::SDL_GL_ACCELERATED_VISUAL as u32;
/// OpenGL context major version.
const CONTEXT_MAJOR_VERSION = bind::SDL_GL_CONTEXT_MAJOR_VERSION as u32;
/// OpenGL context minor version.
const CONTEXT_MINOR_VERSION = bind::SDL_GL_CONTEXT_MINOR_VERSION as u32;
/// The value of a [`super::GlContextFlag`].
const CONTEXT_FLAGS = bind::SDL_GL_CONTEXT_FLAGS as u32;
/// The type of OpenGL context such as Core, Compatibility, ES, or etc.
const CONTEXT_PROFILE_MASK = bind::SDL_GL_CONTEXT_PROFILE_MASK as u32;
/// OpenGL context sharing.
const SHARE_WITH_CURRENT_CONTEXT = bind::SDL_GL_SHARE_WITH_CURRENT_CONTEXT as u32;
/// Whether to request sRGB capable visual.
const FRAMEBUFFER_SRGB_CAPABLE = bind::SDL_GL_FRAMEBUFFER_SRGB_CAPABLE as u32;
/// Setting what does on releasing OpenGL context. Can be set 0 (none) or 1 (flush).
const CONTEXT_RELEASE_BEHAVIOR = bind::SDL_GL_CONTEXT_RELEASE_BEHAVIOR as u32;
/// Whether to notify on reset the OpenGL context.
const CONTEXT_RESET_NOTIFICATION = bind::SDL_GL_CONTEXT_RESET_NOTIFICATION as u32;
/// Whether to disable all errors from OpenGL implementation. It might increase the performance and decrease power usage. But some inconsistency occurs the undefined behavior.
const CONTEXT_NO_ERROR = bind::SDL_GL_CONTEXT_NO_ERROR as u32;
}
}
/// An attrubte of the OpenGL context.
pub struct GlAttribute<'gl> {
attr: GlAttributeKind,
_phantom: PhantomData<&'gl GlContext<'gl>>,
}
impl std::fmt::Debug for GlAttribute<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("GlAttribute")
.field("attr", &self.attr)
.finish_non_exhaustive()
}
}
assert_not_impl_all!(GlAttribute: Send, Sync);
impl<'gl> GlAttribute<'gl> {
/// Constructs an attribute from context and kind.
#[must_use]
pub fn new(_: &'gl GlContext<'gl>, attr: GlAttributeKind) -> Self {
Self {
attr,
_phantom: PhantomData,
}
}
/// Sets an attribute value.
///
/// # Errors
///
/// Returns `Err` if failed to set a value for the attribute.
pub fn set(&self, value: i32) -> Result<()> {
let ret = unsafe { bind::SDL_GL_SetAttribute(self.attr.bits() as EnumInt, value) };
if ret != 0 {
return Err(SdlError::Others { msg: Sdl::error() });
}
Ok(())
}
/// Gets an attribute value.
///
/// # Errors
///
/// Returns `Err` if failed to get a value of the attribute.
pub fn get(&self) -> Result<i32> {
let mut value = 0;
let ret = unsafe { bind::SDL_GL_GetAttribute(self.attr.bits() as EnumInt, &mut value) };
if ret != 0 {
return Err(SdlError::Others { msg: Sdl::error() });
}
Ok(value)
}
}