Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

306 linhas
6.9 KiB

  1. use crate::{
  2. buffer::{Buffer, BufferRef, Target},
  3. error::Error,
  4. misc::{AsEnum, BindGuard, Bindable},
  5. };
  6. /* VertexArray */
  7. pub struct VertexArray<T = Buffer> {
  8. id: gl::GLuint,
  9. buffers: Vec<T>,
  10. }
  11. impl<T> VertexArray<T> {
  12. pub fn builder() -> Builder<T> {
  13. Builder::default()
  14. }
  15. pub fn buffers(&self) -> &[T] {
  16. &self.buffers
  17. }
  18. pub fn buffers_mut(&mut self) -> &mut [T] {
  19. &mut self.buffers
  20. }
  21. }
  22. impl<T> Drop for VertexArray<T> {
  23. fn drop(&mut self) {
  24. gl::delete_vertex_arrays(1, &self.id);
  25. }
  26. }
  27. impl<T> Bindable for VertexArray<T> {
  28. fn bind(&self) {
  29. gl::bind_vertex_array(self.id);
  30. }
  31. fn unbind(&self) {
  32. gl::bind_vertex_array(0);
  33. }
  34. }
  35. /* Builder */
  36. pub struct Builder<T> {
  37. bindings: Vec<Binding<T>>,
  38. }
  39. impl<T> Builder<T> {
  40. pub fn bind_buffer(mut self, buffer: T) -> BindingBuilder<T> {
  41. let binding = Binding {
  42. buffer,
  43. pointers: Vec::new(),
  44. };
  45. self.bindings.push(binding);
  46. BindingBuilder { builder: self }
  47. }
  48. }
  49. impl<T> Builder<T>
  50. where
  51. for<'a> &'a T: BufferRef,
  52. {
  53. pub fn build(self) -> Result<VertexArray<T>, Error> {
  54. let mut id = 0;
  55. Error::checked(|| gl::create_vertex_arrays(1, &mut id))?;
  56. let mut vertex_array = VertexArray {
  57. id,
  58. buffers: Vec::new(),
  59. };
  60. let guard = BindGuard::new(&vertex_array);
  61. let mut buffers = Vec::new();
  62. for binding in self.bindings {
  63. let guard = BindGuard::new((Target::ArrayBuffer, binding.buffer.as_ref()));
  64. for pointer in binding.pointers {
  65. Error::checked(|| gl::enable_vertex_attrib_array(pointer.index))?;
  66. match pointer.type_ {
  67. DataType::Byte
  68. | DataType::UnsignedByte
  69. | DataType::Short
  70. | DataType::UnsignedShort
  71. | DataType::Int
  72. | DataType::UnsignedInt => Error::checked(|| {
  73. gl::vertex_attrib_i_pointer(
  74. pointer.index,
  75. pointer.size,
  76. pointer.type_.as_enum(),
  77. pointer.stride,
  78. pointer.offset as *const _,
  79. )
  80. })?,
  81. _ => Error::checked(|| {
  82. gl::vertex_attrib_pointer(
  83. pointer.index,
  84. pointer.size,
  85. pointer.type_.as_enum(),
  86. if pointer.normalize {
  87. gl::TRUE
  88. } else {
  89. gl::FALSE
  90. },
  91. pointer.stride,
  92. pointer.offset as *const _,
  93. )
  94. })?,
  95. }
  96. if let Some(divisor) = pointer.divisor {
  97. Error::checked(|| gl::vertex_attrib_divisor(pointer.index, divisor))?;
  98. }
  99. }
  100. drop(guard);
  101. buffers.push(binding.buffer);
  102. }
  103. drop(guard);
  104. vertex_array.buffers = buffers;
  105. Ok(vertex_array)
  106. }
  107. }
  108. impl<T> Clone for Builder<T>
  109. where
  110. T: Clone,
  111. {
  112. fn clone(&self) -> Self {
  113. Self {
  114. bindings: self.bindings.clone(),
  115. }
  116. }
  117. }
  118. impl<T> Default for Builder<T> {
  119. fn default() -> Self {
  120. Self {
  121. bindings: Vec::new(),
  122. }
  123. }
  124. }
  125. /* BindingBuilder */
  126. pub struct BindingBuilder<T> {
  127. builder: Builder<T>,
  128. }
  129. impl<T> BindingBuilder<T> {
  130. pub fn bind_buffer(self, buffer: T) -> Self {
  131. self.builder.bind_buffer(buffer)
  132. }
  133. pub fn vertex_attrib_pointer(
  134. mut self,
  135. index: gl::GLuint,
  136. size: gl::GLint,
  137. type_: DataType,
  138. normalize: bool,
  139. stride: gl::GLsizei,
  140. offset: gl::GLsizei,
  141. ) -> Result<Self, Error> {
  142. for binding in &self.builder.bindings {
  143. for pointer in &binding.pointers {
  144. if pointer.index == index {
  145. return Err(Error::VertexArrayIndexAlreadyInUse(index));
  146. }
  147. }
  148. }
  149. let pointer = Pointer {
  150. index,
  151. size,
  152. type_,
  153. normalize,
  154. stride,
  155. offset,
  156. divisor: None,
  157. };
  158. self.builder
  159. .bindings
  160. .last_mut()
  161. .unwrap()
  162. .pointers
  163. .push(pointer);
  164. Ok(self)
  165. }
  166. pub fn vertex_attrib_divisor(mut self, divisor: gl::GLuint) -> Result<Self, Error> {
  167. let binding = self.builder.bindings.last_mut().unwrap();
  168. let pointer = binding
  169. .pointers
  170. .last_mut()
  171. .ok_or(Error::VertexArrayExpectedPointer)?;
  172. pointer.divisor = Some(divisor);
  173. Ok(self)
  174. }
  175. }
  176. impl<T> BindingBuilder<T>
  177. where
  178. for<'a> &'a T: BufferRef,
  179. {
  180. pub fn build(self) -> Result<VertexArray<T>, Error> {
  181. self.builder.build()
  182. }
  183. }
  184. impl<T> Clone for BindingBuilder<T>
  185. where
  186. T: Clone,
  187. {
  188. fn clone(&self) -> Self {
  189. Self {
  190. builder: self.builder.clone(),
  191. }
  192. }
  193. }
  194. /* DataType */
  195. #[allow(non_camel_case_types)]
  196. #[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
  197. pub enum DataType {
  198. Byte,
  199. UnsignedByte,
  200. Short,
  201. UnsignedShort,
  202. Int,
  203. UnsignedInt,
  204. HalfFloat,
  205. Float,
  206. Double,
  207. Fixed,
  208. Int_2_10_10_10_Rev,
  209. UnsignedInt_2_10_10_10_Rev,
  210. UnsignedInt_10f_11f_11f_Rev,
  211. }
  212. impl AsEnum for DataType {
  213. fn as_enum(&self) -> gl::GLenum {
  214. match self {
  215. Self::Byte => gl::BYTE,
  216. Self::UnsignedByte => gl::UNSIGNED_BYTE,
  217. Self::Short => gl::SHORT,
  218. Self::UnsignedShort => gl::UNSIGNED_SHORT,
  219. Self::Int => gl::INT,
  220. Self::UnsignedInt => gl::UNSIGNED_INT,
  221. Self::HalfFloat => gl::HALF_FLOAT,
  222. Self::Float => gl::FLOAT,
  223. Self::Double => gl::DOUBLE,
  224. Self::Fixed => gl::FIXED,
  225. Self::Int_2_10_10_10_Rev => gl::INT_2_10_10_10_REV,
  226. Self::UnsignedInt_2_10_10_10_Rev => gl::UNSIGNED_INT_2_10_10_10_REV,
  227. Self::UnsignedInt_10f_11f_11f_Rev => gl::UNSIGNED_INT_10F_11F_11F_REV,
  228. }
  229. }
  230. }
  231. /* Binding */
  232. struct Binding<T> {
  233. buffer: T,
  234. pointers: Vec<Pointer>,
  235. }
  236. impl<T> Clone for Binding<T>
  237. where
  238. T: Clone,
  239. {
  240. fn clone(&self) -> Self {
  241. Self {
  242. buffer: self.buffer.clone(),
  243. pointers: self.pointers.clone(),
  244. }
  245. }
  246. }
  247. /* Pointer */
  248. #[derive(Clone, Debug)]
  249. pub struct Pointer {
  250. pub index: gl::GLuint,
  251. pub size: gl::GLint,
  252. pub type_: DataType,
  253. pub normalize: bool,
  254. pub stride: gl::GLsizei,
  255. pub offset: gl::GLsizei,
  256. pub divisor: Option<gl::GLuint>,
  257. }