summaryrefslogtreecommitdiff
path: root/engine/src/opengl
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2023-11-02 20:22:33 +0100
committerHampusM <hampus@hampusmat.com>2023-11-02 20:22:33 +0100
commit9aafb51e0be1720019db1c3d0a294ce9a42653df (patch)
tree40881ff26bff5a928280223d8aced87e1370d63b /engine/src/opengl
parentf2c54d47e6b61198520824117339aaa21c32accd (diff)
feat(engine): add texturing
Diffstat (limited to 'engine/src/opengl')
-rw-r--r--engine/src/opengl/mod.rs1
-rw-r--r--engine/src/opengl/texture.rs144
2 files changed, 145 insertions, 0 deletions
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<Self>, dimens: &Vec2<u32>, 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<Self>, 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<Self>, 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<Self>, 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,
+ }
+ }
+}