mirror of
https://github.com/italicsjenga/mini_gl_fb.git
synced 2024-11-25 08:51:31 +11:00
Add safety check for update_buffer
This commit is contained in:
parent
68cda2a7fb
commit
c2702fa36b
|
@ -51,8 +51,6 @@ See the docs for more info.
|
|||
|
||||
Listed in rough order of importance and ease (which are surprisingly correlated here!).
|
||||
|
||||
- Bounds check on `update_buffer` which will currently segfault if you pass the wrong size.
|
||||
|
||||
- Shader playground. Add a method for using shadertoy-like fragment shaders to be applied to
|
||||
your submitted pixel data.
|
||||
|
||||
|
|
20
examples/wrong_sized_buffer.rs
Normal file
20
examples/wrong_sized_buffer.rs
Normal file
|
@ -0,0 +1,20 @@
|
|||
extern crate mini_gl_fb;
|
||||
|
||||
use mini_gl_fb::{Config, BufferFormat};
|
||||
|
||||
fn main() {
|
||||
let mut fb = mini_gl_fb::get_fancy(Config {
|
||||
window_title: "Hello world!",
|
||||
window_size: (800.0, 600.0),
|
||||
buffer_size: (2, 2),
|
||||
.. Default::default()
|
||||
});
|
||||
|
||||
fb.change_buffer_format::<u8>(BufferFormat::RG);
|
||||
|
||||
// This should panic! We should only be providing two components but we provide 4!
|
||||
let buffer = vec![[0u8, 50, 128, 255]; 4];
|
||||
fb.update_buffer(&buffer);
|
||||
|
||||
fb.persist();
|
||||
}
|
36
src/core.rs
36
src/core.rs
|
@ -17,6 +17,7 @@ use gl;
|
|||
use gl::types::*;
|
||||
|
||||
use std::ptr::null;
|
||||
use std::mem::size_of_val;
|
||||
|
||||
/// Create a context using glutin given a configuration.
|
||||
pub fn init_glutin_context<S: ToString>(
|
||||
|
@ -216,10 +217,22 @@ pub struct Framebuffer {
|
|||
|
||||
impl Framebuffer {
|
||||
pub fn update_buffer<T>(&mut self, image_data: &[T]) {
|
||||
// TODO: Safety check on the length of the passed slice so this is actually a safe method
|
||||
// Check the length of the passed slice so this is actually a safe method.
|
||||
let (format, kind) = self.texture_format;
|
||||
let expected_size_in_bytes = size_of_gl_type_enum(kind)
|
||||
* format.components()
|
||||
* self.buffer_width as usize
|
||||
* self.buffer_height as usize;
|
||||
let actual_size_in_bytes = size_of_val(image_data);
|
||||
if actual_size_in_bytes != expected_size_in_bytes {
|
||||
panic!(
|
||||
"Expected a buffer of {} bytes, instead recieved one of {} bytes",
|
||||
expected_size_in_bytes,
|
||||
actual_size_in_bytes
|
||||
);
|
||||
}
|
||||
self.draw(|fb| {
|
||||
unsafe {
|
||||
let (format, kind) = fb.texture_format;
|
||||
gl::TexImage2D(
|
||||
gl::TEXTURE_2D,
|
||||
0,
|
||||
|
@ -317,6 +330,18 @@ pub enum BufferFormat {
|
|||
BGRA = gl::BGRA,
|
||||
}
|
||||
|
||||
impl BufferFormat {
|
||||
fn components(&self) -> usize {
|
||||
use self::BufferFormat::*;
|
||||
match self {
|
||||
R => 1,
|
||||
RG => 2,
|
||||
RGB | BGR => 3,
|
||||
RGBA | BGRA => 4,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ToGlType {
|
||||
fn to_gl_enum() -> GLenum;
|
||||
}
|
||||
|
@ -342,6 +367,13 @@ impl_ToGlType!(
|
|||
i8, gl::BYTE,
|
||||
);
|
||||
|
||||
fn size_of_gl_type_enum(gl_enum: GLenum) -> usize {
|
||||
match gl_enum {
|
||||
gl::UNSIGNED_BYTE | gl::BYTE => 1,
|
||||
_ => panic!("Must pass a GL enum representing a type"),
|
||||
}
|
||||
}
|
||||
|
||||
fn create_texture(width: i32, height: i32, format: BufferFormat, buffer_kind: GLenum) -> GLuint {
|
||||
unsafe {
|
||||
let mut tex = 0;
|
||||
|
|
|
@ -160,6 +160,11 @@ impl MiniGlFb {
|
|||
/// Updates the backing buffer and draws immediately (swaps buffers).
|
||||
///
|
||||
/// The main drawing function.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the size of the buffer does not exactly match the correct size of the texture
|
||||
/// data required based on the buffers format.
|
||||
pub fn update_buffer<T>(&mut self, image_data: &[T]) {
|
||||
self.internal.update_buffer(image_data);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue