|
- use crate::{
- buffer::{Buffer, BufferRef, Target},
- error::Error,
- misc::{BindGuard, Bindable},
- };
-
- /* TransformFeedback */
-
- pub struct TransformFeedback<T = Buffer> {
- id: gl::GLuint,
- buffers: Vec<T>,
- }
-
- impl<T> TransformFeedback<T> {
- pub fn builder() -> Builder<T> {
- Builder::default()
- }
-
- pub fn id(&self) -> gl::GLuint {
- self.id
- }
-
- pub fn buffers(&self) -> &[T] {
- &self.buffers
- }
-
- pub fn buffers_mut(&mut self) -> &mut [T] {
- &mut self.buffers
- }
- }
-
- impl<T> Drop for TransformFeedback<T> {
- fn drop(&mut self) {
- gl::delete_transform_feedbacks(1, &self.id);
- }
- }
-
- impl<T> Bindable for TransformFeedback<T> {
- fn bind(&self) {
- gl::bind_transform_feedback(gl::TRANSFORM_FEEDBACK, self.id);
- }
-
- fn unbind(&self) {
- gl::bind_transform_feedback(gl::TRANSFORM_FEEDBACK, 0);
- }
- }
-
- /* Builder */
-
- pub struct Builder<T> {
- bindings: Vec<Binding<T>>,
- }
-
- impl<T> Builder<T>
- where
- for<'a> &'a T: BufferRef,
- {
- pub fn bind_buffer(mut self, index: gl::GLuint, buffer: T) -> Result<Builder<T>, Error> {
- for binding in &self.bindings {
- if binding.index == index {
- return Err(Error::TransformFeedbackIndexAlreadyInUse(index));
- }
- }
-
- let binding = Binding { buffer, index };
-
- self.bindings.push(binding);
-
- Ok(self)
- }
-
- pub fn build(self) -> Result<TransformFeedback<T>, Error> {
- let mut id = 0;
-
- Error::checked(|| gl::create_transform_feedbacks(1, &mut id))?;
-
- let mut transform_feedback = TransformFeedback {
- id,
- buffers: Vec::new(),
- };
-
- let guard = BindGuard::new(&transform_feedback);
-
- let mut buffers = Vec::new();
- for binding in self.bindings {
- Error::checked(|| {
- binding
- .buffer
- .as_ref()
- .bind_buffer_base(Target::TransformFeedbackBuffer, binding.index)
- })?;
-
- buffers.push(binding.buffer);
- }
-
- drop(guard);
-
- transform_feedback.buffers = buffers;
-
- Ok(transform_feedback)
- }
- }
-
- impl<T> Default for Builder<T> {
- fn default() -> Self {
- Self {
- bindings: Vec::new(),
- }
- }
- }
-
- /* Binding */
-
- struct Binding<T> {
- buffer: T,
- index: gl::GLuint,
- }
|