# HG changeset patch # User alfadur # Date 1564782869 -10800 # Node ID 6382a14c9e8315f6975a16fc8d01ea9ac79b5081 # Parent ae8e14d14596a4222b8fa813496f1c81f17b5dc0 add an empty texture constructor diff -r ae8e14d14596 -r 6382a14c9e83 rust/lib-hedgewars-engine/src/render/gl.rs --- a/rust/lib-hedgewars-engine/src/render/gl.rs Fri Aug 02 13:35:23 2019 +0200 +++ b/rust/lib-hedgewars-engine/src/render/gl.rs Sat Aug 03 00:54:29 2019 +0300 @@ -1,6 +1,6 @@ -use integral_geometry::Rect; +use integral_geometry::{Rect, Size}; -use std::{ffi, ffi::CString, mem, ptr, slice}; +use std::{ffi, ffi::CString, mem, num::NonZeroU32, ptr, slice}; #[derive(Default)] pub struct PipelineState { @@ -32,73 +32,115 @@ #[derive(Debug)] pub struct Texture2D { - pub handle: u32, + pub handle: Option, } impl Drop for Texture2D { fn drop(&mut self) { - if self.handle != 0 { + if let Some(handle) = self.handle { unsafe { - gl::DeleteTextures(1, &self.handle); + gl::DeleteTextures(1, &handle.get()); } } } } +fn new_texture() -> Option { + let mut handle = 0; + unsafe { + gl::GenTextures(1, &mut handle); + } + NonZeroU32::new(handle) +} + +fn tex_params(filter: u32) { + unsafe { + gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_S, gl::CLAMP_TO_EDGE as i32); + gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_T, gl::CLAMP_TO_EDGE as i32); + gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, filter as i32); + gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, filter as i32); + } +} + impl Texture2D { + pub fn new(size: Size, internal_format: u32, format: u32, ty: u32, filter: u32) -> Self { + if let Some(handle) = new_texture() { + unsafe { + gl::BindTexture(gl::TEXTURE_2D, handle.get()); + gl::TexImage2D( + gl::TEXTURE_2D, + 0, + internal_format as i32, + size.width as i32, + size.height as i32, + 0, + format as u32, + ty, + std::ptr::null(), + ) + } + + tex_params(filter); + Self { + handle: Some(handle), + } + } else { + Self { handle: None } + } + } + pub fn with_data( data: &[u8], data_stride: u32, - width: u32, - height: u32, + size: Size, internal_format: u32, format: u32, ty: u32, filter: u32, ) -> Self { - let mut handle = 0; - - unsafe { - gl::GenTextures(1, &mut handle); + if let Some(handle) = new_texture() { + unsafe { + gl::BindTexture(gl::TEXTURE_2D, handle.get()); + gl::PixelStorei(gl::UNPACK_ROW_LENGTH, data_stride as i32); + gl::TexImage2D( + gl::TEXTURE_2D, + 0, + internal_format as i32, + size.width as i32, + size.height as i32, + 0, + format as u32, + ty, + data.as_ptr() as *const _, + ) + } - gl::BindTexture(gl::TEXTURE_2D, handle); - gl::PixelStorei(gl::UNPACK_ROW_LENGTH, data_stride as i32); - gl::TexImage2D( - gl::TEXTURE_2D, - 0, - internal_format as i32, - width as i32, - height as i32, - 0, - format as u32, - ty, - data.as_ptr() as *const _, - ); - - gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_S, gl::CLAMP_TO_EDGE as i32); - gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_T, gl::CLAMP_TO_EDGE as i32); - gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, filter as i32); - gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, filter as i32); + tex_params(filter); + Self { + handle: Some(handle), + } + } else { + Self { handle: None } } - - Texture2D { handle } } pub fn update(&self, region: Rect, data: &[u8], data_stride: u32, format: u32, ty: u32) { - unsafe { - gl::BindTexture(gl::TEXTURE_2D, self.handle); - gl::PixelStorei(gl::UNPACK_ROW_LENGTH, data_stride as i32); - gl::TexSubImage2D( - gl::TEXTURE_2D, - 0, // texture level - region.left(), // texture region - region.top(), - region.width() as i32 - 1, - region.height() as i32 - 1, - format, // data format - ty, // data type - data.as_ptr() as *const _, // data ptr - ); + if let Some(handle) = self.handle { + unsafe { + gl::BindTexture(gl::TEXTURE_2D, handle.get()); + gl::PixelStorei(gl::UNPACK_ROW_LENGTH, data_stride as i32); + gl::TexSubImage2D( + gl::TEXTURE_2D, + 0, // texture level + region.left(), // texture region + region.top(), + region.right(), + region.bottom(), + format, // data format + ty, // data type + data.as_ptr() as *const _, // data ptr + ); + } } } } @@ -352,9 +394,11 @@ pub fn bind_texture_2d(&self, index: u32, texture: &Texture2D) { self.bind(); - unsafe { - gl::ActiveTexture(gl::TEXTURE0 + index); - gl::BindTexture(gl::TEXTURE_2D, texture.handle); + if let Some(handle) = texture.handle { + unsafe { + gl::ActiveTexture(gl::TEXTURE0 + index); + gl::BindTexture(gl::TEXTURE_2D, handle.get()); + } } } }