diff --git a/font.png b/font.png index f8eb352..ab42c49 100644 Binary files a/font.png and b/font.png differ diff --git a/src/bin/pumpkin.rs b/src/bin/pumpkin.rs index dac8c43..821f445 100644 --- a/src/bin/pumpkin.rs +++ b/src/bin/pumpkin.rs @@ -474,6 +474,11 @@ struct RenderableArrow { color: Vec3, } +struct TriangleStream { + pub verts: gpu_buffers::VertexBuffer, + pub indices: gpu_buffers::IndexBuffer, +} + struct GameGraphics { passes: Vec , @@ -486,6 +491,8 @@ struct GameGraphics { mesh_arrow: RenderableModel, mesh_truck: RenderableModel, + text_stream: TriangleStream, + texture_sky: Texture, texture_grass: Texture, texture_font: Texture, @@ -802,6 +809,14 @@ impl GameGraphics { }, ]; + let text_stream = TriangleStream { + verts: gpu_buffers::VertexBuffer::streaming (4 * 5 * 6 * 1024), + indices: { + let v: Vec = (0u32..6 * 1024).collect (); + gpu_buffers::IndexBuffer::from_slice_u32 (&v) + } + }; + Self { passes, shaders, @@ -813,6 +828,8 @@ impl GameGraphics { mesh_arrow, mesh_truck, + text_stream, + texture_sky, texture_grass, texture_font, @@ -1090,14 +1107,14 @@ impl GameGraphics { let font_size = (8.0, 18.0); - let mvp = Mat4::from_scale ((2.0 * 256.0 / screen_size.0, 2.0 * 72.0 / screen_size.1, 1.0).into ()); + let mvp = Mat4::from_scale ((2.0 * 256.0 / screen_size.0, 2.0 * 256.0 / screen_size.1, 1.0).into ()); glezz::uniform_matrix_4fv (unis [&MVP], &mvp); let pos: Vec = vec! [ + -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 1.0, 0.0, 0.0, - 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, + -1.0, 1.0, 0.0, ]; use std::convert::TryInto; diff --git a/src/gpu_buffers.rs b/src/gpu_buffers.rs index 6e9ef09..cb0aa74 100644 --- a/src/gpu_buffers.rs +++ b/src/gpu_buffers.rs @@ -18,7 +18,7 @@ const FLOAT_SIZE: usize = 4; impl VertexBuffer { // len is the number of floats - fn allocate_buffer (len: usize) -> u32 { + fn allocate_buffer (len: usize, usage: u32) -> u32 { let mut id = 0; unsafe { gl::GenBuffers (1, &mut id); @@ -29,7 +29,7 @@ impl VertexBuffer { gl::ARRAY_BUFFER, (len * FLOAT_SIZE).try_into ().unwrap (), std::ptr::null (), - gl::STATIC_DRAW + usage ); } assert! (id != 0); @@ -41,7 +41,7 @@ impl VertexBuffer { .map (|slice| slice.len ()) .sum (); - let id = Self::allocate_buffer (len); + let id = Self::allocate_buffer (len, gl::STATIC_DRAW); let mut offset = 0; for slice in slices.iter () { @@ -67,6 +67,17 @@ impl VertexBuffer { Self::from_slices (&[slice]) } + // len is the number of floats + + pub fn streaming (len: usize) -> Self { + let id = Self::allocate_buffer (len, gl::STREAM_DRAW); + + Self { + id, + len, + } + } + pub fn bind (&self) { unsafe { gl::BindBuffer (gl::ARRAY_BUFFER, self.id); @@ -87,15 +98,21 @@ impl Drop for VertexBuffer { } } +/// A buffer of triangle indices in OpenGL server memory pub struct IndexBuffer { + /// The OpenGL ID of the buffer id: u32, - // Not bytes. Number of indexes. + + /// The count of 32-bit indices the buffer can store len: usize, + + /// The largest index stored in the buffer when it was created max: u32, } impl IndexBuffer { - pub fn from_slice (slice: &[u8]) -> Self { + /// Interprets a u8 slice as a u32 slice + pub fn from_slice_u8 (slice: &[u8]) -> Self { let mut rdr = Cursor::new (slice); let mut max = None; @@ -132,6 +149,28 @@ impl IndexBuffer { } } + pub fn from_slice_u32 (slice: &[u32]) -> Self { + let max = slice.iter ().max (); + + let id = { + let mut id = 0; + unsafe { + gl::GenBuffers (1, &mut id); + gl::BindBuffer (gl::ELEMENT_ARRAY_BUFFER, id); + + gl::BufferData (gl::ELEMENT_ARRAY_BUFFER, (slice.len () * 4).try_into ().unwrap (), &slice [0] as *const u32 as *const c_void, gl::STATIC_DRAW); + } + assert! (id != 0); + id + }; + + Self { + id, + len: slice.len (), + max: *max.unwrap (), + } + } + pub fn bind (&self) { unsafe { gl::BindBuffer (gl::ELEMENT_ARRAY_BUFFER, self.id); diff --git a/src/renderable_model.rs b/src/renderable_model.rs index 52a0990..6513efe 100644 --- a/src/renderable_model.rs +++ b/src/renderable_model.rs @@ -71,7 +71,7 @@ impl RenderableModel { let vertexes = VertexBuffer::from_slice (&vertex_vec); let index_slice = model.get_all_indexes (); - let indexes = IndexBuffer::from_slice (index_slice); + let indexes = IndexBuffer::from_slice_u8 (index_slice); let max_index: usize = indexes.max ().try_into ().unwrap ();