Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

223 рядки
5.2 KiB

  1. use std::mem::swap;
  2. use std::rc::Rc;
  3. use glc::{
  4. buffer::Buffer,
  5. misc::BindGuard,
  6. transform_feedback::TransformFeedback,
  7. vertex_array::{BindingBuilder, DataType, Pointer, VertexArray},
  8. };
  9. use space_crush_common::return_if_none;
  10. use crate::Error;
  11. type VertexArrayBuilder = BindingBuilder<Rc<Buffer>>;
  12. /* Particles */
  13. pub struct Particles {
  14. input: Buffers,
  15. output: Buffers,
  16. }
  17. impl Particles {
  18. pub fn builder() -> Builder {
  19. Builder::default()
  20. }
  21. pub fn update(&mut self) {
  22. let update_array = return_if_none!(&self.input.update_array);
  23. gl::enable(gl::RASTERIZER_DISCARD);
  24. let guard_buffer = BindGuard::new(update_array);
  25. let guard_transform_feedback = BindGuard::new(&self.output.transform_feedback);
  26. gl::begin_transform_feedback(gl::POINTS);
  27. // TODO gl::draw_arrays(mode, 0, count as _);
  28. gl::end_transform_feedback();
  29. gl::disable(gl::RASTERIZER_DISCARD);
  30. drop(guard_buffer);
  31. drop(guard_transform_feedback);
  32. swap(&mut self.input, &mut self.output);
  33. }
  34. }
  35. /* Buffer */
  36. struct Buffers {
  37. transform_feedback: TransformFeedback<Rc<Buffer>>,
  38. update_array: Option<VertexArray<Rc<Buffer>>>,
  39. render_array: Option<VertexArray<Rc<Buffer>>>,
  40. }
  41. impl Buffers {
  42. fn from_builder(builder: &Builder) -> Result<Self, Error> {
  43. let mut transform_feedback = TransformFeedback::builder();
  44. let mut update_array: Option<VertexArrayBuilder> = None;
  45. let mut render_array: Option<VertexArrayBuilder> = None;
  46. let mut index = 0;
  47. for b in &builder.buffers {
  48. if b.render_pointers.is_empty() && b.update_pointers.is_empty() {
  49. continue;
  50. }
  51. let buffer = Rc::new(Buffer::new()?);
  52. transform_feedback = transform_feedback.bind_buffer(index, buffer.clone())?;
  53. update_array = update_vertex_array(update_array, &buffer, &b.update_pointers)?;
  54. render_array = update_vertex_array(render_array, &buffer, &b.render_pointers)?;
  55. index += 1;
  56. }
  57. let transform_feedback = transform_feedback.build()?;
  58. let update_array = match update_array {
  59. Some(update_array) => Some(update_array.build()?),
  60. None => None,
  61. };
  62. let render_array = match render_array {
  63. Some(render_array) => Some(render_array.build()?),
  64. None => None,
  65. };
  66. Ok(Self {
  67. transform_feedback,
  68. update_array,
  69. render_array,
  70. })
  71. }
  72. }
  73. fn update_vertex_array(
  74. mut builder: Option<VertexArrayBuilder>,
  75. buffer: &Rc<Buffer>,
  76. pointers: &[Pointer],
  77. ) -> Result<Option<VertexArrayBuilder>, Error> {
  78. if !pointers.is_empty() {
  79. builder = match builder {
  80. Some(builder) => Some(builder.bind_buffer(buffer.clone())),
  81. None => Some(VertexArray::builder().bind_buffer(buffer.clone())),
  82. };
  83. for p in pointers {
  84. builder = Some(builder.unwrap().vertex_attrib_pointer(
  85. p.index,
  86. p.size,
  87. p.type_,
  88. p.normalize,
  89. p.stride,
  90. p.offset,
  91. )?);
  92. }
  93. }
  94. Ok(builder)
  95. }
  96. /* Builder */
  97. #[derive(Default)]
  98. pub struct Builder {
  99. buffers: Vec<BufferData>,
  100. }
  101. impl Builder {
  102. pub fn add_buffer(mut self) -> BufferBuilder {
  103. self.buffers.push(BufferData::default());
  104. BufferBuilder { builder: self }
  105. }
  106. fn build(self) -> Result<Particles, Error> {
  107. let input = Buffers::from_builder(&self)?;
  108. let output = Buffers::from_builder(&self)?;
  109. Ok(Particles { input, output })
  110. }
  111. }
  112. /* BufferBuilder */
  113. #[derive(Default)]
  114. pub struct BufferBuilder {
  115. builder: Builder,
  116. }
  117. impl BufferBuilder {
  118. pub fn add_buffer(self) -> BufferBuilder {
  119. self.builder.add_buffer()
  120. }
  121. pub fn update_attrib_pointer(
  122. mut self,
  123. index: gl::GLuint,
  124. size: gl::GLint,
  125. type_: DataType,
  126. normalize: bool,
  127. stride: gl::GLsizei,
  128. offset: gl::GLsizei,
  129. ) -> Result<Self, Error> {
  130. self.builder
  131. .buffers
  132. .last_mut()
  133. .unwrap()
  134. .update_pointers
  135. .push(Pointer {
  136. index,
  137. size,
  138. type_,
  139. normalize,
  140. stride,
  141. offset,
  142. divisor: None,
  143. });
  144. Ok(self)
  145. }
  146. pub fn render_attrib_pointer(
  147. mut self,
  148. index: gl::GLuint,
  149. size: gl::GLint,
  150. type_: DataType,
  151. normalize: bool,
  152. stride: gl::GLsizei,
  153. offset: gl::GLsizei,
  154. ) -> Result<Self, Error> {
  155. self.builder
  156. .buffers
  157. .last_mut()
  158. .unwrap()
  159. .render_pointers
  160. .push(Pointer {
  161. index,
  162. size,
  163. type_,
  164. normalize,
  165. stride,
  166. offset,
  167. divisor: None,
  168. });
  169. Ok(self)
  170. }
  171. pub fn build(self) -> Result<Particles, Error> {
  172. self.builder.build()
  173. }
  174. }
  175. /* BufferData */
  176. #[derive(Default)]
  177. struct BufferData {
  178. update_pointers: Vec<Pointer>,
  179. render_pointers: Vec<Pointer>,
  180. }