reverie_engine_opengl/
vao.rs1pub mod buffer;
3pub mod color_vao;
4pub mod config;
5pub mod renderer;
6pub mod texture_vao;
7pub mod vertex;
8
9use std::mem;
10use std::os::raw::c_void;
11
12use crate::gl;
13use crate::gl::types::{GLenum, GLfloat, GLint, GLsizei, GLsizeiptr};
14use crate::gl::Gl;
15use crate::shader::UniformVariables;
16
17pub use {
18 buffer::VaoBuffer,
19 color_vao::VaoBuilder3DGeometryOutline,
20 config::{VaoConfig, VaoConfigBuilder},
21 renderer::{
22 Color3DRenderer, Color3DRenderingInfo, Phong3DRenderer, Phong3DRenderingInfo,
23 PhongRenderingInfo, Renderer,
24 },
25 texture_vao::builder::{CuboidTextures, VaoBuilder3DGeometry},
26 vertex::{VertexType, VertexWithColor, VertexWithNormUv},
27};
28
29#[derive(Debug)]
31pub struct Vao<'a> {
32 gl: Gl,
33 vao: u32,
34 vbo: u32,
35 vertex_num: i32,
36 config: &'a VaoConfig,
37}
38
39impl<'a> Vao<'a> {
40 #[allow(clippy::too_many_arguments)]
41 unsafe fn new(
45 gl: Gl,
46 size: GLsizeiptr,
47 data: *const c_void,
48 usage: GLenum,
49 num_attributes: usize,
50 attribute_types: &'static [GLenum],
51 attribute_sizes: &'static [GLint],
52 stride: GLsizei,
53 vertex_num: i32,
54 config: &'a VaoConfig,
55 ) -> Self {
56 debug_assert_eq!(num_attributes, attribute_types.len());
57 debug_assert_eq!(num_attributes, attribute_sizes.len());
58
59 let mut vao = 0;
60 let mut vbo = 0;
61
62 unsafe {
63 gl.GenVertexArrays(1, &mut vao);
65 gl.GenBuffers(1, &mut vbo);
66
67 gl.BindVertexArray(vao);
69 gl.BindBuffer(gl::ARRAY_BUFFER, vbo);
70 gl.BufferData(gl::ARRAY_BUFFER, size, data, usage);
71
72 let mut offset = 0;
73 for i in 0..num_attributes {
74 gl.EnableVertexAttribArray(i as u32);
75 gl.VertexAttribPointer(
76 i as u32,
77 attribute_sizes[i],
78 attribute_types[i],
79 gl::FALSE,
80 stride,
81 (offset * mem::size_of::<GLfloat>()) as *const c_void,
82 );
83 offset += attribute_sizes[i] as usize;
84 }
85
86 gl.BindBuffer(gl::ARRAY_BUFFER, 0);
88 gl.BindVertexArray(0);
89 }
90
91 Vao {
92 gl,
93 vao,
94 vbo,
95 vertex_num,
96 config,
97 }
98 }
99
100 fn draw(&self, _uniforms: &UniformVariables, draw_mode: GLenum) {
101 unsafe {
102 if self.config.depth_test {
103 self.gl.Enable(gl::DEPTH_TEST);
104 } else {
105 self.gl.Disable(gl::DEPTH_TEST);
106 }
107
108 if self.config.blend {
109 self.gl.Enable(gl::BLEND);
110 self.gl.BlendFunc(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA);
111 } else {
112 self.gl.Disable(gl::BLEND);
113 }
114
115 if self.config.wireframe {
116 self.gl.PolygonMode(gl::FRONT_AND_BACK, gl::LINE);
117 } else {
118 self.gl.PolygonMode(gl::FRONT_AND_BACK, gl::FILL);
119 }
120
121 if self.config.culling {
122 self.gl.Enable(gl::CULL_FACE);
123 } else {
124 self.gl.Disable(gl::CULL_FACE);
125 }
126
127 self.gl.BindVertexArray(self.vao);
128 self.gl.DrawArrays(draw_mode, 0, self.vertex_num);
129 self.gl.BindVertexArray(0);
130 self.gl.BindTexture(gl::TEXTURE_2D, 0);
131 }
132 }
133
134 fn draw_triangles(&self, uniforms: &UniformVariables) {
136 self.draw(uniforms, gl::TRIANGLES);
137 }
138}
139
140impl<'a> Drop for Vao<'a> {
141 fn drop(&mut self) {
142 unsafe {
143 if self.vbo > 0 {
144 self.gl.DeleteBuffers(1, &self.vbo as _);
145 }
146 if self.vao > 0 {
147 self.gl.DeleteVertexArrays(1, &self.vao as _);
148 }
149 }
150 }
151}