129 data: &[u8], |
129 data: &[u8], |
130 data_stride: Option<NonZeroU32>, |
130 data_stride: Option<NonZeroU32>, |
131 size: Size, |
131 size: Size, |
132 internal_format: TextureInternalFormat, |
132 internal_format: TextureInternalFormat, |
133 format: TextureFormat, |
133 format: TextureFormat, |
134 ty: TextureDataType, |
134 data_type: TextureDataType, |
135 filter: TextureFilter, |
135 filter: TextureFilter, |
136 ) -> Self { |
136 ) -> Self { |
137 if is_out_of_bounds(data, data_stride, size) { |
137 if is_out_of_bounds(data, data_stride, size) { |
138 return Self { handle: None, size }; |
138 return Self { handle: None, size }; |
139 } |
139 } |
214 } |
214 } |
215 } |
215 } |
216 } |
216 } |
217 } |
217 } |
218 |
218 |
|
219 #[derive(Clone, Copy, Debug)] |
|
220 #[repr(u32)] |
|
221 pub enum BufferType { |
|
222 Array = gl::ARRAY_BUFFER, |
|
223 ElementArray = gl::ELEMENT_ARRAY_BUFFER, |
|
224 } |
|
225 |
|
226 #[derive(Clone, Copy, Debug)] |
|
227 #[repr(u32)] |
|
228 pub enum BufferUsage { |
|
229 DynamicDraw = gl::DYNAMIC_DRAW, |
|
230 } |
|
231 |
219 #[derive(Debug)] |
232 #[derive(Debug)] |
220 pub struct Buffer { |
233 pub struct Buffer { |
221 pub handle: u32, |
234 pub handle: Option<NonZeroU32>, |
222 pub ty: u32, |
235 pub buffer_type: BufferType, |
223 pub usage: u32, |
236 pub usage: BufferUsage, |
224 } |
237 } |
225 |
238 |
226 impl Buffer { |
239 impl Buffer { |
227 pub fn empty( |
240 pub fn empty(buffer_type: BufferType, usage: BufferUsage) -> Buffer { |
228 ty: u32, |
|
229 usage: u32, |
|
230 //size: isize |
|
231 ) -> Buffer { |
|
232 let mut buffer = 0; |
241 let mut buffer = 0; |
233 |
242 |
234 unsafe { |
243 unsafe { |
235 gl::GenBuffers(1, &mut buffer); |
244 gl::GenBuffers(1, &mut buffer); |
236 gl::BindBuffer(ty, buffer); |
|
237 //gl::BufferData(ty, size, ptr::null_mut(), usage); |
|
238 } |
245 } |
239 |
246 |
240 Buffer { |
247 Buffer { |
241 handle: buffer, |
248 handle: NonZeroU32::new(buffer), |
242 ty, |
249 buffer_type: buffer_type, |
243 usage, |
250 usage, |
244 } |
251 } |
245 } |
252 } |
246 |
253 |
247 fn with_data(ty: u32, usage: u32, data: &[u8]) -> Buffer { |
254 fn with_data(buffer_type: BufferType, usage: BufferUsage, data: &[u8]) -> Buffer { |
248 let mut buffer = 0; |
255 let mut buffer = 0; |
249 |
256 |
250 unsafe { |
257 unsafe { |
251 gl::GenBuffers(1, &mut buffer); |
258 gl::GenBuffers(1, &mut buffer); |
252 gl::BindBuffer(ty, buffer); |
259 if buffer != 0 { |
253 gl::BufferData(ty, data.len() as isize, data.as_ptr() as _, usage); |
260 gl::BindBuffer(buffer_type as u32, buffer); |
|
261 gl::BufferData( |
|
262 buffer_type as u32, |
|
263 data.len() as isize, |
|
264 data.as_ptr() as _, |
|
265 usage as u32, |
|
266 ); |
|
267 } |
254 } |
268 } |
255 |
269 |
256 Buffer { |
270 Buffer { |
257 handle: buffer, |
271 handle: NonZeroU32::new(buffer), |
258 ty, |
272 buffer_type, |
259 usage, |
273 usage, |
260 } |
274 } |
261 } |
275 } |
262 |
276 |
263 pub fn ty(&self) -> u32 { |
277 pub fn ty(&self) -> BufferType { |
264 self.ty |
278 self.buffer_type |
265 } |
279 } |
266 |
280 |
267 pub fn handle(&self) -> u32 { |
281 pub fn handle(&self) -> Option<NonZeroU32> { |
268 self.handle |
282 self.handle |
269 } |
283 } |
270 |
284 |
271 pub fn write_typed<T>(&self, data: &[T]) { |
285 pub fn write_typed<T>(&self, data: &[T]) { |
272 unsafe { |
286 if let Some(handle) = self.handle { |
273 let data = |
287 unsafe { |
274 slice::from_raw_parts(data.as_ptr() as *const u8, data.len() * mem::size_of::<T>()); |
288 gl::BindBuffer(self.buffer_type as u32, handle.get()); |
275 |
289 gl::BufferData( |
276 gl::BindBuffer(self.ty, self.handle); |
290 self.buffer_type as u32, |
277 gl::BufferData( |
291 (data.len() * mem::size_of::<T>()) as isize, |
278 self.ty, |
292 data.as_ptr() as *const _, |
279 data.len() as isize, |
293 self.usage as u32, |
280 data.as_ptr() as *const _ as *const _, |
294 ); |
281 self.usage, |
295 } |
282 ); |
|
283 } |
296 } |
284 } |
297 } |
285 |
298 |
286 pub fn write(&self, data: &[u8]) { |
299 pub fn write(&self, data: &[u8]) { |
287 unsafe { |
300 if let Some(handle) = self.handle { |
288 gl::BindBuffer(self.ty, self.handle); |
301 unsafe { |
289 gl::BufferData( |
302 gl::BindBuffer(self.buffer_type as u32, handle.get()); |
290 self.ty, |
303 gl::BufferData( |
291 data.len() as isize, |
304 self.buffer_type as u32, |
292 data.as_ptr() as *const _ as *const _, |
305 data.len() as isize, |
293 self.usage, |
306 data.as_ptr() as *const _, |
294 ); |
307 self.usage as u32, |
|
308 ); |
|
309 } |
295 } |
310 } |
296 } |
311 } |
297 } |
312 } |
298 |
313 |
299 impl Drop for Buffer { |
314 impl Drop for Buffer { |
300 fn drop(&mut self) { |
315 fn drop(&mut self) { |
301 unsafe { |
316 if let Some(handle) = self.handle { |
302 gl::DeleteBuffers(1, &self.handle); |
317 let handle = handle.get(); |
|
318 unsafe { |
|
319 gl::DeleteBuffers(1, &handle); |
|
320 } |
303 } |
321 } |
304 } |
322 } |
305 } |
323 } |
306 |
324 |
307 #[derive(Debug)] |
325 #[derive(Debug)] |
329 pub fn new<'a>( |
347 pub fn new<'a>( |
330 vs: &str, |
348 vs: &str, |
331 ps: Option<&str>, |
349 ps: Option<&str>, |
332 bindings: &[VariableBinding<'a>], |
350 bindings: &[VariableBinding<'a>], |
333 ) -> Result<Self, String> { |
351 ) -> Result<Self, String> { |
334 unsafe fn compile_shader(ty: u32, shdr: &str) -> Result<u32, String> { |
352 unsafe fn compile_shader(shader_type: u32, shader_code: &str) -> Result<u32, String> { |
335 let shader = gl::CreateShader(ty); |
353 let shader = gl::CreateShader(shader_type); |
336 let len = shdr.len() as i32; |
354 let len = shader_code.len() as i32; |
337 let shdr = shdr.as_ptr() as *const i8; |
355 let code_strings = shader_code.as_ptr() as *const i8; |
338 gl::ShaderSource(shader, 1, &shdr, &len); |
356 gl::ShaderSource(shader, 1, &code_strings, &len); |
339 gl::CompileShader(shader); |
357 gl::CompileShader(shader); |
340 |
358 |
341 let mut success = 0i32; |
359 let mut success = 0i32; |
342 gl::GetShaderiv(shader, gl::COMPILE_STATUS, &mut success as _); |
360 gl::GetShaderiv(shader, gl::COMPILE_STATUS, &mut success as _); |
343 |
361 |
522 gl::GenVertexArrays(1, &mut vao); |
540 gl::GenVertexArrays(1, &mut vao); |
523 gl::BindVertexArray(vao); |
541 gl::BindVertexArray(vao); |
524 } |
542 } |
525 |
543 |
526 for &(slot, ref buffer) in buffers { |
544 for &(slot, ref buffer) in buffers { |
527 unsafe { |
545 if let Some(handle) = buffer.handle() { |
528 gl::BindBuffer(buffer.ty(), buffer.handle()); |
546 unsafe { |
|
547 gl::BindBuffer(buffer.ty() as u32, handle.get()); |
|
548 } |
529 } |
549 } |
530 |
550 |
531 for attr in self.elements.iter().filter(|a| a.buffer_slot == slot) { |
551 for attr in self.elements.iter().filter(|a| a.buffer_slot == slot) { |
532 unsafe { |
552 unsafe { |
533 gl::EnableVertexAttribArray(attr.shader_slot); |
553 gl::EnableVertexAttribArray(attr.shader_slot); |