1use crate::buffer::{Content, Buffer, BufferAny, BufferType, BufferMode, BufferCreationError};
2use crate::buffer::{BufferSlice, BufferMutSlice};
3use crate::uniforms::{AsUniformValue, UniformBlock, UniformValue, LayoutMismatchError};
4use crate::program;
5
6use crate::gl;
7use crate::GlObject;
8
9use std::ops::{Deref, DerefMut};
10
11use crate::backend::Facade;
12
13#[derive(Debug)]
28pub struct UniformBuffer<T: ?Sized> where T: Content {
29 buffer: Buffer<T>,
30}
31
32#[derive(Debug)]
34pub struct TypelessUniformBuffer {
35 buffer: BufferAny,
36}
37
38impl<T: ?Sized + Content> GlObject for UniformBuffer<T> {
39 type Id = gl::types::GLuint;
40
41 #[inline]
42 fn get_id(&self) -> gl::types::GLuint {
43 self.buffer.get_id()
44 }
45}
46
47impl<T> UniformBuffer<T> where T: Copy {
48 #[inline]
50 pub fn new<F: ?Sized>(facade: &F, data: T) -> Result<UniformBuffer<T>, BufferCreationError>
51 where F: Facade
52 {
53 UniformBuffer::new_impl(facade, data, BufferMode::Default)
54 }
55
56 #[inline]
58 pub fn dynamic<F: ?Sized>(facade: &F, data: T) -> Result<UniformBuffer<T>, BufferCreationError>
59 where F: Facade
60 {
61 UniformBuffer::new_impl(facade, data, BufferMode::Dynamic)
62 }
63
64 #[inline]
66 pub fn persistent<F: ?Sized>(facade: &F, data: T) -> Result<UniformBuffer<T>, BufferCreationError>
67 where F: Facade
68 {
69 UniformBuffer::new_impl(facade, data, BufferMode::Persistent)
70 }
71
72 #[inline]
74 pub fn immutable<F: ?Sized>(facade: &F, data: T) -> Result<UniformBuffer<T>, BufferCreationError>
75 where F: Facade
76 {
77 UniformBuffer::new_impl(facade, data, BufferMode::Immutable)
78 }
79
80 #[inline]
81 fn new_impl<F: ?Sized>(facade: &F, data: T, mode: BufferMode)
82 -> Result<UniformBuffer<T>, BufferCreationError>
83 where F: Facade
84 {
85 let buffer = Buffer::new(facade, &data, BufferType::UniformBuffer, mode)?;
86
87 Ok(UniformBuffer {
88 buffer,
89 })
90 }
91
92 #[inline]
94 pub fn empty<F: ?Sized>(facade: &F) -> Result<UniformBuffer<T>, BufferCreationError> where F: Facade {
95 UniformBuffer::empty_impl(facade, BufferMode::Default)
96 }
97
98 #[inline]
100 pub fn empty_dynamic<F: ?Sized>(facade: &F) -> Result<UniformBuffer<T>, BufferCreationError>
101 where F: Facade
102 {
103 UniformBuffer::empty_impl(facade, BufferMode::Dynamic)
104 }
105
106 #[inline]
108 pub fn empty_persistent<F: ?Sized>(facade: &F) -> Result<UniformBuffer<T>, BufferCreationError>
109 where F: Facade
110 {
111 UniformBuffer::empty_impl(facade, BufferMode::Persistent)
112 }
113
114 #[inline]
116 pub fn empty_immutable<F: ?Sized>(facade: &F) -> Result<UniformBuffer<T>, BufferCreationError>
117 where F: Facade
118 {
119 UniformBuffer::empty_impl(facade, BufferMode::Immutable)
120 }
121
122 #[inline]
123 fn empty_impl<F: ?Sized>(facade: &F, mode: BufferMode) -> Result<UniformBuffer<T>, BufferCreationError>
124 where F: Facade
125 {
126 let buffer = Buffer::empty(facade, BufferType::UniformBuffer, mode)?;
127
128 Ok(UniformBuffer {
129 buffer,
130 })
131 }
132}
133
134impl<T: ?Sized> UniformBuffer<T> where T: Content {
135 #[inline]
142 pub fn empty_unsized<F: ?Sized>(facade: &F, size: usize)
143 -> Result<UniformBuffer<T>, BufferCreationError>
144 where F: Facade
145 {
146 UniformBuffer::empty_unsized_impl(facade, size, BufferMode::Default)
147 }
148
149 #[inline]
156 pub fn empty_unsized_dynamic<F: ?Sized>(facade: &F, size: usize)
157 -> Result<UniformBuffer<T>, BufferCreationError>
158 where F: Facade
159 {
160 UniformBuffer::empty_unsized_impl(facade, size, BufferMode::Dynamic)
161 }
162
163 #[inline]
170 pub fn empty_unsized_persistent<F: ?Sized>(facade: &F, size: usize)
171 -> Result<UniformBuffer<T>, BufferCreationError>
172 where F: Facade
173 {
174 UniformBuffer::empty_unsized_impl(facade, size, BufferMode::Persistent)
175 }
176
177 #[inline]
184 pub fn empty_unsized_immutable<F: ?Sized>(facade: &F, size: usize)
185 -> Result<UniformBuffer<T>, BufferCreationError>
186 where F: Facade
187 {
188 UniformBuffer::empty_unsized_impl(facade, size, BufferMode::Immutable)
189 }
190
191 #[inline]
192 fn empty_unsized_impl<F: ?Sized>(facade: &F, size: usize, mode: BufferMode)
193 -> Result<UniformBuffer<T>, BufferCreationError>
194 where F: Facade
195 {
196 let buffer = Buffer::empty_unsized(facade, BufferType::UniformBuffer, size, mode)?;
197
198 Ok(UniformBuffer {
199 buffer,
200 })
201 }
202}
203
204impl<T: ?Sized> Deref for UniformBuffer<T> where T: Content {
205 type Target = Buffer<T>;
206
207 #[inline]
208 fn deref(&self) -> &Buffer<T> {
209 &self.buffer
210 }
211}
212
213impl<T: ?Sized> DerefMut for UniformBuffer<T> where T: Content {
214 #[inline]
215 fn deref_mut(&mut self) -> &mut Buffer<T> {
216 &mut self.buffer
217 }
218}
219
220impl<'a, T: ?Sized> From<&'a UniformBuffer<T>> for BufferSlice<'a, T> where T: Content {
221 #[inline]
222 fn from(b: &'a UniformBuffer<T>) -> BufferSlice<'a, T> {
223 b.buffer.as_slice()
224 }
225}
226
227impl<'a, T: ?Sized> From<&'a mut UniformBuffer<T>> for BufferMutSlice<'a, T> where T: Content {
228 #[inline]
229 fn from(b: &'a mut UniformBuffer<T>) -> BufferMutSlice<'a, T> {
230 b.buffer.as_mut_slice()
231 }
232}
233
234impl<'a, T: ?Sized> AsUniformValue for &'a UniformBuffer<T> where T: UniformBlock + Content {
235 #[inline]
236 fn as_uniform_value(&self) -> UniformValue<'_> {
237 #[inline]
238 fn f<T: ?Sized>(block: &program::UniformBlock)
239 -> Result<(), LayoutMismatchError> where T: UniformBlock + Content
240 {
241 T::matches(&block.layout, 0)
243 }
244
245 UniformValue::Block(self.buffer.as_slice_any(), f::<T>)
246 }
247}