1
2#![allow(dead_code)]
3
4pub mod glbuffer;
6
7pub mod glshader;
9
10pub mod glcmdbuf;
12
13pub mod gltexture;
15
16pub mod glframebuffer;
18
19pub mod buffervec;
21
22pub mod mesh;
24
25pub mod material;
27
28pub mod pipeline;
30
31pub mod meshset;
33
34pub mod common;
36
37extern crate nalgebra_glm as glm;
38
39pub mod prelude {
41 pub use crate::glbuffer::*;
42 pub use crate::glshader::*;
43 pub use crate::glcmdbuf::*;
44 pub use crate::gltexture::*;
45 pub use crate::glframebuffer::*;
46 pub use crate::buffervec::*;
47 pub use crate::mesh::*;
48 pub use crate::material::*;
49 pub use crate::pipeline::*;
50 pub use crate::meshset::*;
51 pub use crate::common::*;
52 pub use crate::derive_vertex_type;
53 pub use glm::*;
54 pub use struct_iterable::Iterable;
55 pub use glcore::*;
56 pub use half::f16;
57}
58
59pub use prelude::*;
60
61#[cfg(test)]
62mod tests {
63 use std::{
64 ffi::c_void,
65 mem::size_of_val,
66 process::ExitCode,
67 rc::Rc,
68 };
69 use super::prelude::*;
70 use glfw::*;
71
72 derive_vertex_type! {
73 pub struct MyVertex {
74 position: Vec2,
75 }
76 }
77
78 #[derive(Debug)]
79 enum AppError {
80 GLFWInitErr,
81 GLFWCreateWindowFailed,
82 GLFWErr(glfw::Error),
83 }
84
85 #[derive(Debug)]
86 struct Renderer {
87 pipeline: Rc<Pipeline<MyVertex, UnusedType>>,
88 shader: Rc<Shader>,
89 mesh: Rc<dyn GenericMeshWithMaterial>,
90 }
91
92 #[derive(Debug)]
93 struct AppInstance {
94 renderer: Option<Renderer>,
95 glcore: Rc<GLCore>,
96 events: GlfwReceiver<(f64, WindowEvent)>,
97 window: PWindow,
98 glfw: Glfw,
99 }
100
101 impl Renderer {
102 fn new(glcore: Rc<GLCore>) -> Self {
103 let vertices = [
104 MyVertex{position: Vec2::new(-1.0, -1.0)},
105 MyVertex{position: Vec2::new( 1.0, -1.0)},
106 MyVertex{position: Vec2::new(-1.0, 1.0)},
107 MyVertex{position: Vec2::new( 1.0, 1.0)},
108 ];
109 let elements = [
110 0u8, 1u8, 2u8,
111 1u8, 3u8, 2u8,
112 ];
113 let vertex_buffer = Buffer::new(glcore.clone(), BufferTarget::ArrayBuffer, size_of_val(&vertices), BufferUsage::StaticDraw, vertices.as_ptr() as *const c_void);
114 let mut vertex_buffer = BufferVecStatic::<MyVertex>::new(glcore.clone(), vertex_buffer);
115 vertex_buffer.resize(4, MyVertex::default());
116 let element_buffer = Buffer::new(glcore.clone(), BufferTarget::ElementArrayBuffer, size_of_val(&elements), BufferUsage::StaticDraw, elements.as_ptr() as *const c_void);
117 let mut element_buffer = BufferVecStatic::<u8>::new(glcore.clone(), element_buffer);
118 element_buffer.resize(6, 0u8);
119 let mesh = StaticMesh::<MyVertex, u8, UnusedType, UnusedType>::new(PrimitiveMode::Triangles, vertex_buffer, Some(element_buffer), None, None);
120 let mesh = Rc::new(MeshWithMaterial::new(mesh, Rc::new(MaterialLegacy::default())));
121 let mesh: Rc<dyn GenericMeshWithMaterial> = mesh;
122 let shader = Rc::new(Shader::new(glcore.clone(),
123 Some("
124#version 330\n
125
126in vec2 position;
127
128void main()
129{
130 gl_Position = vec4(position, 0.0, 1.0);
131}
132 "),
133 None,
134 Some("
135#version 330\n
136
137out vec4 Color;
138
139void main()
140{
141 Color = vec4(0.0, 0.0, 0.5, 1.0);
142}
143 ")
144 ).unwrap());
145 let pipeline = Rc::new(Pipeline::new(glcore.clone(), mesh.clone(), shader.clone()));
146 Self {
147 mesh,
148 shader,
149 pipeline,
150 }
151 }
152
153 fn render(&self, glcore: &GLCore) {
154 glcore.glClearColor(0.0, 0.3, 0.5, 1.0);
155 glcore.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
156
157 let p_bind = self.pipeline.bind();
158 p_bind.draw(None);
159 p_bind.unbind();
160 }
161 }
162
163 impl AppInstance {
164 pub fn new() -> Result<Self, AppError> {
165 let mut glfw = match glfw::init_no_callbacks() {
166 Ok(glfw) => glfw,
167 Err(_) => return Err(AppError::GLFWInitErr), };
169 let (mut window, events) = glfw.create_window(1024, 768, "GLFW Window", glfw::WindowMode::Windowed).ok_or(AppError::GLFWCreateWindowFailed)?;
170 window.set_key_polling(true);
171 window.make_current();
172 glfw.set_swap_interval(SwapInterval::Adaptive);
173 let glcore = Rc::new(GLCore::new(|proc_name|window.get_proc_address(proc_name)));
174 let renderer = Some(Renderer::new(glcore.clone()));
175 Ok(Self {
176 renderer,
177 glcore,
178 events,
179 window,
180 glfw,
181 })
182 }
183
184 pub fn run(&mut self, timeout: Option<f64>) -> ExitCode {
185 let start_debug_time = self.glfw.get_time();
186 while !self.window.should_close() {
187 let time_cur_frame = self.glfw.get_time();
188
189 if let Some(renderer) = self.renderer.as_ref() {
190 renderer.render(&self.glcore);
191 self.window.swap_buffers();
192 }
193
194 self.glfw.poll_events();
195 for (_, event) in glfw::flush_messages(&self.events) {
196 match event {
197 glfw::WindowEvent::Key(Key::Escape, _, Action::Press, _) => {
198 self.window.set_should_close(true)
199 }
200 _ => {}
201 }
202 }
203
204 if let Some(timeout) = timeout {
205 if time_cur_frame - start_debug_time >= timeout {
206 self.window.set_should_close(true)
207 }
208 }
209 }
210
211 ExitCode::from(0)
212 }
213 }
214
215 #[test]
216 fn test_glfw() -> ExitCode {
217 const DEBUG_TIME: f64 = 10.0;
218 let mut test_app = match AppInstance::new() {
219 Ok(app) => app,
220 Err(e) => {
221 eprintln!("GLFW App Initialize failed: {:?}", e);
222 return ExitCode::from(2)
223 }
224 };
225 test_app.run(Some(DEBUG_TIME))
226 }
227}