From 9aafb51e0be1720019db1c3d0a294ce9a42653df Mon Sep 17 00:00:00 2001 From: HampusM Date: Thu, 2 Nov 2023 20:22:33 +0100 Subject: feat(engine): add texturing --- engine/src/opengl/mod.rs | 1 + engine/src/opengl/texture.rs | 144 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 145 insertions(+) create mode 100644 engine/src/opengl/texture.rs (limited to 'engine/src/opengl') diff --git a/engine/src/opengl/mod.rs b/engine/src/opengl/mod.rs index 4f4f96f..d58ca50 100644 --- a/engine/src/opengl/mod.rs +++ b/engine/src/opengl/mod.rs @@ -6,6 +6,7 @@ use crate::vector::Vec2; pub mod buffer; pub mod currently_bound; pub mod shader; +pub mod texture; pub mod vertex_array; mod util; diff --git a/engine/src/opengl/texture.rs b/engine/src/opengl/texture.rs new file mode 100644 index 0000000..c7bf75b --- /dev/null +++ b/engine/src/opengl/texture.rs @@ -0,0 +1,144 @@ +use crate::opengl::currently_bound::CurrentlyBound; +use crate::vector::Vec2; + +#[derive(Debug)] +pub struct Texture +{ + texture: gl::types::GLuint, +} + +impl Texture +{ + pub fn new() -> Self + { + let mut texture = gl::types::GLuint::default(); + + unsafe { + gl::GenTextures(1, &mut texture); + }; + + Self { texture } + } + + pub fn bind(&self, cb: impl FnOnce(CurrentlyBound<'_, Self>)) + { + unsafe { + gl::BindTexture(gl::TEXTURE_2D, self.texture); + } + + // SAFETY: The buffer object is bound above + let currently_bound = unsafe { CurrentlyBound::new() }; + + cb(currently_bound); + } + + pub fn generate(_: &CurrentlyBound, dimens: &Vec2, data: &[u8]) + { + #[allow(clippy::cast_possible_wrap)] + unsafe { + gl::TexImage2D( + gl::TEXTURE_2D, + 0, + gl::RGB as i32, + dimens.x as i32, + dimens.y as i32, + 0, + gl::RGB, + gl::UNSIGNED_BYTE, + data.as_ptr().cast(), + ); + + gl::GenerateMipmap(gl::TEXTURE_2D); + } + } + + pub fn set_wrap(_: CurrentlyBound, wrapping: Wrapping) + { + let wrapping_gl = wrapping.to_gl(); + + #[allow(clippy::cast_possible_wrap)] + unsafe { + gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_S, wrapping_gl as i32); + gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_T, wrapping_gl as i32); + } + } + + pub fn set_magnifying_filter(_: CurrentlyBound, filtering: Filtering) + { + let filtering_gl = filtering.to_gl(); + + #[allow(clippy::cast_possible_wrap)] + unsafe { + gl::TexParameteri( + gl::TEXTURE_2D, + gl::TEXTURE_MAG_FILTER, + filtering_gl as i32, + ); + } + } + + pub fn set_minifying_filter(_: CurrentlyBound, filtering: Filtering) + { + let filtering_gl = filtering.to_gl(); + + #[allow(clippy::cast_possible_wrap)] + unsafe { + gl::TexParameteri( + gl::TEXTURE_2D, + gl::TEXTURE_MIN_FILTER, + filtering_gl as i32, + ); + } + } +} + +impl Drop for Texture +{ + fn drop(&mut self) + { + unsafe { + gl::DeleteTextures(1, &self.texture); + } + } +} + +/// Texture wrapping. +#[derive(Debug, Clone, Copy)] +pub enum Wrapping +{ + Repeat, + MirroredRepeat, + ClampToEdge, + ClampToBorder, +} + +impl Wrapping +{ + fn to_gl(self) -> gl::types::GLenum + { + match self { + Self::Repeat => gl::REPEAT, + Self::MirroredRepeat => gl::MIRRORED_REPEAT, + Self::ClampToEdge => gl::CLAMP_TO_EDGE, + Self::ClampToBorder => gl::CLAMP_TO_BORDER, + } + } +} + +#[derive(Debug, Clone, Copy)] +pub enum Filtering +{ + Nearest, + Linear, +} + +impl Filtering +{ + fn to_gl(self) -> gl::types::GLenum + { + match self { + Self::Linear => gl::LINEAR, + Self::Nearest => gl::NEAREST, + } + } +} -- cgit v1.2.3-18-g5258