Add a few more buffer customization methods

This commit is contained in:
shivshank 2018-07-27 19:30:10 -04:00
parent 2cd65b90b1
commit 68cda2a7fb
3 changed files with 83 additions and 12 deletions

View file

@ -111,6 +111,9 @@ pub fn init_framebuffer(
);
gl::BindBuffer(gl::ARRAY_BUFFER, 0);
gl::BindVertexArray(0);
// So the user doesn't have to consider alignment in their buffer
gl::PixelStorei(gl::PACK_ALIGNMENT, 1);
}
Framebuffer {
@ -247,21 +250,22 @@ impl Framebuffer {
self.relink_program();
}
// TODO: require passing new image data
pub fn change_buffer_format<T: ToGlType>(&mut self, format: BufferFormat) {
pub fn use_grayscale_shader(&mut self) {
self.use_fragment_shader(include_str!("./grayscale_fragment_shader.glsl"));
}
pub fn change_buffer_format<T: ToGlType>(
&mut self,
format: BufferFormat,
) {
self.texture_format = (format, T::to_gl_enum());
}
// TODO: resize_buffer
pub fn resize_buffer(&mut self, buffer_width: u32, buffer_height: u32) {
self.buffer_width = buffer_width as _;
self.buffer_height = buffer_height as _;
}
/// Set the size of the OpenGL viewport.
///
/// This does not resize the window or image buffer, only the area to which OpenGL draws. You
/// only need to call this function when you are handling events manually and have a resizable
/// window.
///
/// You will know if you need to call this function, as in that case only part of the window
/// will be getting drawn, typically after an update.
pub fn resize_viewport(&mut self, width: u32, height: u32) {
self.vp_width = width as _;
self.vp_height = height as _;

View file

@ -0,0 +1,11 @@
#version 330 core
in vec2 v_uv;
out vec4 frag_color;
uniform sampler2D u_tex0;
void main() {
frag_color = texture(u_tex0, v_uv).rrra;
}

View file

@ -17,7 +17,7 @@
//! ```
//!
//! The default buffer format is 32bit RGBA, so every pixel is four bytes. Buffer[0] is the top
//! left pixel.
//! left pixel. The buffer should be tightly packed with no padding after each row.
//!
//! # Interlude: Library philosophy
//!
@ -76,6 +76,8 @@ pub use breakout::GlutinBreakout;
pub use config::Config;
pub use core::{Internal, BufferFormat};
use core::ToGlType;
/// Creates a non resizable window and framebuffer with a given size in pixels.
///
/// Please note that the window size is in logical device pixels, so on a high DPI monitor the
@ -162,6 +164,60 @@ impl MiniGlFb {
self.internal.update_buffer(image_data);
}
/// Changes the format of the image buffer.
///
/// OpenGL will interpret any missing components as 0, except the alpha which it will assume is
/// 255. For instance, if you set the format to BufferFormat::RG, OpenGL will render every
/// pixel reading the two values you passed for the first two components, and then assume 0
/// for the blue component, and 255 for the alpha.
///
/// If you want to render in grayscale by providing a single component for each pixel, set
/// the buffer format to BufferFormat::R, and call `use_grayscale_shader` (which will replace
/// the fragment shader with one that sets all components equal to the red component).
///
/// The type `T` does not affect how the texture is sampled, only how the buffer you pass is
/// interpreted. Since there is no way exposed to change the internal format of the texture,
/// (for instance if you wanted to make it an HDR image with floating point components) only
/// the types `u8` and `i8` are supported. Open an issue if you have a use case for other
/// types.
///
/// # Example
///
/// ```rust
/// fb.change_buffer_format::<u8>(BufferFormat::R);
/// fb.use_grayscale_shader();
/// ```
pub fn change_buffer_format<T: ToGlType>(&mut self, format: BufferFormat) {
self.internal.fb.change_buffer_format::<T>(format);
}
/// Resizes the buffer.
///
/// This does not affect the size of the window. The texture will be scaled to fit.
pub fn resize_buffer(&mut self, buffer_width: u32, buffer_height: u32) {
self.internal.fb.resize_buffer(buffer_width, buffer_height);
}
/// Switch to a shader that only uses the first component from your buffer.
///
/// This **does not** switch to a shader which converts RGB(A) images to grayscale, for
/// instance, by preserving percieved luminance.
pub fn use_grayscale_shader(&mut self) {
self.internal.fb.use_grayscale_shader();
}
/// Set the size of the OpenGL viewport (does not trigger a redraw).
///
/// This does not resize the window or image buffer, only the area to which OpenGL draws. You
/// only need to call this function when you are handling events manually and have a resizable
/// window.
///
/// You will know if you need to call this function, as in that case only part of the window
/// will be getting drawn, typically after an update.
pub fn resize_viewport(&mut self, width: u32, height: u32) {
self.internal.fb.resize_viewport(width, height);
}
/// Keeps the window open until the user closes it.
pub fn persist(&mut self) {
self.internal.persist();