Browse Source

context: Cache active buffer

This reduces calls to glUseBuffer.
Johannes Hofmann 7 years ago
parent
commit
43ecb10350
2 changed files with 36 additions and 11 deletions
  1. 24
    11
      src/buffer.rs
  2. 12
    0
      src/context.rs

+ 24
- 11
src/buffer.rs View File

3
 use std::mem;
3
 use std::mem;
4
 
4
 
5
 
5
 
6
+//TODO rename Buffer -> ArrayBuffer?
6
 #[derive(Clone, Debug)]
7
 #[derive(Clone, Debug)]
7
 pub struct Buffer {
8
 pub struct Buffer {
8
-    buffer_obj: u32,
9
+    buffer_id: BufferId,
9
     num_elements: usize,
10
     num_elements: usize,
10
 }
11
 }
11
 
12
 
13
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
14
+pub struct BufferId {
15
+    id: u32,
16
+}
17
+
18
+impl BufferId {
19
+    /// Returns an invalid `BufferId`.
20
+    pub fn invalid() -> Self {
21
+        BufferId{ id: 0 }
22
+    }
23
+
24
+    pub fn index(&self) -> u32 {
25
+        self.id
26
+    }
27
+}
28
+
12
 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
29
 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
13
 pub enum DrawMode {
30
 pub enum DrawMode {
14
     Triangles,
31
     Triangles,
28
 
45
 
29
 impl Buffer {
46
 impl Buffer {
30
     pub fn new(cx: &mut Context, vertex_data: &[f32], num_elements: usize) -> Buffer {
47
     pub fn new(cx: &mut Context, vertex_data: &[f32], num_elements: usize) -> Buffer {
31
-        let mut buffer_obj = 0_u32;
48
+        let mut buffer_id = BufferId { id: 0 };
32
 
49
 
33
         unsafe {
50
         unsafe {
34
-            cx.gl.GenBuffers(1, &mut buffer_obj);
35
-            cx.gl.BindBuffer(context::gl::ARRAY_BUFFER, buffer_obj);
51
+            cx.gl.GenBuffers(1, &mut buffer_id.id);
52
+            cx.bind_buffer(buffer_id);
36
             cx.gl.BufferData(context::gl::ARRAY_BUFFER,
53
             cx.gl.BufferData(context::gl::ARRAY_BUFFER,
37
                              (vertex_data.len() * mem::size_of::<f32>()) as context::gl::types::GLsizeiptr,
54
                              (vertex_data.len() * mem::size_of::<f32>()) as context::gl::types::GLsizeiptr,
38
                              vertex_data.as_ptr() as *const _,
55
                              vertex_data.as_ptr() as *const _,
40
         }
57
         }
41
 
58
 
42
         Buffer {
59
         Buffer {
43
-            buffer_obj,
60
+            buffer_id,
44
             num_elements,
61
             num_elements,
45
         }
62
         }
46
     }
63
     }
47
 
64
 
48
     pub fn set_data(&mut self, cx: &mut Context, vertex_data: &[f32], num_elements: usize) {
65
     pub fn set_data(&mut self, cx: &mut Context, vertex_data: &[f32], num_elements: usize) {
66
+        cx.bind_buffer(self.buffer_id);
49
         unsafe {
67
         unsafe {
50
             cx.gl.BufferData(context::gl::ARRAY_BUFFER,
68
             cx.gl.BufferData(context::gl::ARRAY_BUFFER,
51
                                   (vertex_data.len() * mem::size_of::<f32>()) as context::gl::types::GLsizeiptr,
69
                                   (vertex_data.len() * mem::size_of::<f32>()) as context::gl::types::GLsizeiptr,
55
         self.num_elements = num_elements;
73
         self.num_elements = num_elements;
56
     }
74
     }
57
 
75
 
58
-    pub fn bind(&self, cx: &mut Context) {
59
-        unsafe {
60
-            cx.gl.BindBuffer(context::gl::ARRAY_BUFFER, self.buffer_obj);
61
-        }
62
-    }
63
-
64
     pub fn draw(&self, cx: &mut Context, mode: DrawMode) {
76
     pub fn draw(&self, cx: &mut Context, mode: DrawMode) {
77
+        cx.bind_buffer(self.buffer_id);
65
         unsafe {
78
         unsafe {
66
             cx.gl.DrawArrays(
79
             cx.gl.DrawArrays(
67
                 mode.to_gl_enum(),
80
                 mode.to_gl_enum(),

+ 12
- 0
src/context.rs View File

1
+use buffer::BufferId;
1
 use glutin::GlContext;
2
 use glutin::GlContext;
2
 use glutin;
3
 use glutin;
3
 use program::ProgramId;
4
 use program::ProgramId;
26
     active_texture_unit: TextureUnit,
27
     active_texture_unit: TextureUnit,
27
     next_free_texture_unit: TextureUnit,
28
     next_free_texture_unit: TextureUnit,
28
     active_program: ProgramId,
29
     active_program: ProgramId,
30
+    active_buffer: BufferId,
29
 }
31
 }
30
 
32
 
31
 impl ::std::fmt::Debug for Context {
33
 impl ::std::fmt::Debug for Context {
53
             active_texture_unit: TextureUnit(0),
55
             active_texture_unit: TextureUnit(0),
54
             next_free_texture_unit: TextureUnit(0),
56
             next_free_texture_unit: TextureUnit(0),
55
             active_program: ProgramId::invalid(),
57
             active_program: ProgramId::invalid(),
58
+            active_buffer: BufferId::invalid(),
56
         };
59
         };
57
 
60
 
58
         // Initialize a vertex array object (VAO) if the current OpenGL context supports it. VAOs are
61
         // Initialize a vertex array object (VAO) if the current OpenGL context supports it. VAOs are
169
             self.active_program = prog;
172
             self.active_program = prog;
170
         }
173
         }
171
     }
174
     }
175
+
176
+    pub fn bind_buffer(&mut self, buf: BufferId) {
177
+        if buf != self.active_buffer {
178
+            unsafe {
179
+                self.gl.BindBuffer(gl::ARRAY_BUFFER, buf.index());
180
+            }
181
+            self.active_buffer = buf;
182
+        }
183
+    }
172
 }
184
 }