diff --git a/src/components/program.rs b/src/components/program.rs index 992581b..e926d4d 100644 --- a/src/components/program.rs +++ b/src/components/program.rs @@ -53,34 +53,39 @@ impl Program { self.set_hook("viewport", viewport.snippet()); } - pub fn compile(&mut self, gl: &glow::Context) { + pub fn compile(&mut self, gl: &glow::Context) -> crate::errors::Result<()> { + use crate::errors::Error; unsafe { - let vertex_array = gl - .create_vertex_array() - .expect("Cannot create vertex array"); + // let vertex_array = gl + // .create_vertex_array() + // .expect("Cannot create vertex array"); - let program = gl.create_program().expect("Cannot create program"); + let program = gl.create_program().map_err(|e| Error::InvalidProgram(e))?; let vertex_shader = - self.create_shader(gl, &self.vertex.to_string(), glow::VERTEX_SHADER); + self.create_shader(gl, &self.vertex.to_string(),self.version, glow::VERTEX_SHADER); let fragment_shader = - self.create_shader(gl, &self.fragment.to_string(), glow::FRAGMENT_SHADER); + self.create_shader(gl, &self.fragment.to_string(),self.version, glow::FRAGMENT_SHADER); gl.link_program(program); if !gl.get_program_link_status(program) { - panic!("{}", gl.get_program_info_log(program)); + return Err(Error::InvalidProgram(gl.get_program_info_log(program))); } + gl.detach_shader(program, vertex_shader); gl.detach_shader(program, fragment_shader); self.native_program = Some(program); } + + Ok(()) } fn create_shader( &self, gl: &glow::Context, code: &str, + version: &'static str, shader_type: u32, ) -> ::Shader { let shader = unsafe { diff --git a/src/components/shader.rs b/src/components/shader.rs index 27008b4..4f56c53 100644 --- a/src/components/shader.rs +++ b/src/components/shader.rs @@ -27,7 +27,7 @@ impl std::fmt::Display for Shader { impl Shader { pub fn new>(target: ShaderType, code: CodeType) -> Result { - let code = match code { + let mut code = match code { CodeType::Code(code) => code.borrow().to_string(), CodeType::Path(path) => { let code = find_file(path).expect("Failed to find file"); @@ -35,6 +35,21 @@ impl Shader { } }; + match target { + + glow::VERTEX_SHADER => { + code.insert_str(0, "#define _GLUMPY__VERTEX_SHADER__\n"); + } + + glow::FRAGMENT_SHADER => { + code.insert_str(0, "#define _GLUMPY__FRAGMENT_SHADER__\n"); + } + + _ => { + warn!("Unknown shader type: {}", target); + } + } + let code = merge_includes(code).map_err(|e| Error::InvalidSnippet(e.to_string()))?; let parsed = CodeBlock::new(&code)?; diff --git a/src/errors.rs b/src/errors.rs index 99104f7..3a185eb 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -6,4 +6,10 @@ pub type Result = std::result::Result; pub enum Error { #[error("Invalid Snippet {0}")] InvalidSnippet(String), + + #[error("Invalid Shader {0}")] + InvalidShader(String), + + #[error("Invalid Program {0}")] + InvalidProgram(String), } diff --git a/src/graphics/collections/agg_fast_path.rs b/src/graphics/collections/agg_fast_path.rs index 2043d8d..8f992fe 100644 --- a/src/graphics/collections/agg_fast_path.rs +++ b/src/graphics/collections/agg_fast_path.rs @@ -11,7 +11,7 @@ use crate::graphics::Graphics; use super::Colletion; -struct AggFastPath { +pub struct AggFastPath { program: Program, buffer: Vec, } @@ -35,21 +35,23 @@ impl AggFastPath { uniform float linewidth; - unifrom float antialias; + uniform float antialias; uniform vec4 color; ") ,false, None)?; - print!("{}", input_snippet); + let vertex = vertex.add_snippet_before(input_snippet); - let vertex = vertex.add_snippet_before(input_snippet + fetchcode([], "agg_fast")); - - let mut program = Program::new(vertex, fragment, None, ""); + let mut program = Program::new(vertex, fragment, None, "330 core"); program.set_transform(transform); program.set_viewport(viewport); + println!("{}", program.vertex()); + + println!("{}", program.fragment()); + Ok(Self { program, buffer: Vec::with_capacity(128), @@ -66,6 +68,12 @@ impl Colletion for AggFastPath { } impl Graphics for AggFastPath { + + fn compile(&mut self, gl: &glow::Context) -> Result<()> { + self.program.compile(gl) + } + + fn draw(&self) -> Result<()> { use bytemuck::cast_slice; @@ -251,7 +259,5 @@ mod test { let agg_path = AggFastPath::new(&transform, &viewport).unwrap(); - - } } \ No newline at end of file diff --git a/src/graphics/mod.rs b/src/graphics/mod.rs index 9921da9..c3b9352 100644 --- a/src/graphics/mod.rs +++ b/src/graphics/mod.rs @@ -9,4 +9,6 @@ pub use colormesh::ColorMesh; pub trait Graphics { fn draw(&self) -> Result<()>; + + fn compile(&mut self, gl: &glow::Context) -> Result<()>; } diff --git a/src/support/supporter.rs b/src/support/supporter.rs index c72cd15..5ce1e6b 100644 --- a/src/support/supporter.rs +++ b/src/support/supporter.rs @@ -1,5 +1,16 @@ -use crate::utils::Triangler; -use nalgebra_glm::perspective; +use crate::camera::Camera; +use crate::graphics::Graphics; +use crate::{ + graphics::{ + collections::agg_fast_path::AggFastPath, + transforms::{ + polar::Polar, position::Position, trackball::Trackball, viewport::Viewport, Transform, + }, + }, + utils::Triangler, +}; +use cgmath::InnerSpace; +use glow::HasContext; use glutin::{ config::ConfigTemplateBuilder, context::{ContextAttributesBuilder, NotCurrentGlContext, PossiblyCurrentContext}, @@ -7,18 +18,19 @@ use glutin::{ surface::{GlSurface, Surface, SurfaceAttributesBuilder, WindowSurface}, }; use imgui::Ui; -use imgui_winit_support::{HiDpiMode, winit::{ - dpi::{LogicalSize, PhysicalPosition}, - event_loop::EventLoop, - window::{Window, WindowBuilder}, -}, WinitPlatform}; +use imgui_winit_support::{ + winit::{ + dpi::{LogicalSize, PhysicalPosition}, + event_loop::EventLoop, + window::{Window, WindowBuilder}, + }, + HiDpiMode, WinitPlatform, +}; +use nalgebra_glm::perspective; +use nalgebra_glm::Vec3; use raw_window_handle::HasRawWindowHandle; use std::num::NonZeroU32; use std::time::Instant; -use cgmath::InnerSpace; -use glow::HasContext; -use nalgebra_glm::Vec3; -use crate::camera::Camera; pub fn init(mut run_ui: FUi) where @@ -28,7 +40,6 @@ where let (mut winit_platform, mut imgui_context) = imgui_init(&window); { - let dpi_mode = if let Ok(factor) = std::env::var("IMGUI_EXAMPLE_FORCE_DPI_FACTOR") { // Allow forcing of HiDPI factor for debugging purposes match factor.parse::() { @@ -55,14 +66,26 @@ where let mut last_frame = Instant::now(); let tri_renderer = Triangler::new(ig_renderer.gl_context(), "#version 330"); + let viewport = Trackball::new().unwrap(); + let trans = Polar::new().unwrap(); + let position = Position::new().unwrap(); + + let transform = viewport.chain(trans.chain(position)); + + let viewport = Viewport::new().unwrap(); + + let mut agg_path = AggFastPath::new(&transform, &viewport).unwrap(); + + agg_path.compile(ig_renderer.gl_context()).unwrap(); + let program = tri_renderer.program(); let mut camera = Camera::new( - Vec3::new(0.5, 0.5, 1.0), // Camera position (world location - Vec3::new(0.0, 1.0, 0.0), // Upward vector + Vec3::new(0.5, 0.5, 1.0), // Camera position (world location + Vec3::new(0.0, 1.0, 0.0), // Upward vector Vec3::new(0.0, 0.0, -1.0), // Look at vector ); - let mut last_position: Option> = None; + let mut last_position: Option> = None; let mut yaw = -90.0; let mut pitch = 0.0; @@ -97,7 +120,8 @@ where let loc = gl.get_uniform_location(program, "projection"); let size = window.inner_size(); - let projection = perspective(size.width as f32 / size.height as f32, 45.0, 0.1, 100.0); + let projection = + perspective(size.width as f32 / size.height as f32, 45.0, 0.1, 100.0); gl.uniform_matrix_4_f32_slice(loc.as_ref(), false, projection.as_slice()); let loc = gl.get_uniform_location(program, "view"); @@ -112,7 +136,14 @@ where if ui.is_mouse_pos_valid(ui.io().mouse_pos) { let mouse_pos = ui.io().mouse_pos; if ui.is_mouse_dragging(imgui::MouseButton::Right) { - mouse_callback(&mut last_position, PhysicalPosition::new(mouse_pos[0] as f64, mouse_pos[1] as f64), 0.05, &mut pitch, &mut yaw, &mut camera); + mouse_callback( + &mut last_position, + PhysicalPosition::new(mouse_pos[0] as f64, mouse_pos[1] as f64), + 0.05, + &mut pitch, + &mut yaw, + &mut camera, + ); } } @@ -166,8 +197,15 @@ where .unwrap() } -fn mouse_callback(last_position: &mut Option>, current_position:PhysicalPosition, sensitivity: f64, pitch: &mut f64, yaw: &mut f64, camera: &mut Camera) { - use cgmath::{Euler, Deg, Quaternion}; +fn mouse_callback( + last_position: &mut Option>, + current_position: PhysicalPosition, + sensitivity: f64, + pitch: &mut f64, + yaw: &mut f64, + camera: &mut Camera, +) { + use cgmath::{Deg, Euler, Quaternion}; let xpos = current_position.x; let ypos = current_position.y; @@ -197,11 +235,7 @@ fn mouse_callback(last_position: &mut Option>, current_pos *pitch = -89.0; } - let euler_deg = Euler::new( - Deg(*pitch), - Deg(*yaw), - Deg(0.0), - ); + let euler_deg = Euler::new(Deg(*pitch), Deg(*yaw), Deg(0.0)); let c = Quaternion::from(euler_deg).normalize(); diff --git a/src/utils/parser.rs b/src/utils/parser.rs index d499023..6052a1c 100644 --- a/src/utils/parser.rs +++ b/src/utils/parser.rs @@ -137,7 +137,7 @@ fn include(input: &str) -> IResult<&str, Include> { )) } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq)] pub enum Modifier { Const, Static, @@ -1282,6 +1282,83 @@ impl CodeBlock { pub fn mangling>(&mut self, suffix: S) -> HashMap { let mut map = HashMap::new(); + + fn _expression_mangling(exp: &mut Expression, map: &HashMap) { + match exp { + Expression::Variable(v) => { + if let Some(new) = map.get(v) { + *v = new.clone(); + } + } + + Expression::FunctionCall { parameters, .. } => { + for para in parameters.iter_mut() { + _expression_mangling(para, map); + } + } + + Expression::Assignment { left, right } => { + _expression_mangling(left, map); + _expression_mangling(right, map); + } + + Expression::StructMemberAccess { base, .. } => { + _expression_mangling(base, map); + } + + Expression::StructPointerAccess { base, .. } => { + _expression_mangling(base, map); + } + + _ => {} + } + } + + fn _mangling_block(block: &mut Statement, map: &HashMap) { + if let Statement::Block(b) = block { + for statement in b.iter_mut() { + match statement.as_mut() { + Statement::DoWhile { condition, .. } => { + _expression_mangling(condition, map); + } + + Statement::Expression(e) => { + _expression_mangling(e, map); + } + + Statement::If { condition, block } => { + _expression_mangling(condition, map); + _mangling_block(block, map); + } + + Statement::While { condition, block } => { + _expression_mangling(condition, map); + _mangling_block(block, map); + } + + Statement::For { condition, block } => { + _expression_mangling(condition, map); + _mangling_block(block, map); + } + + Statement::Declaration { value, .. } => { + if let Some(v) = value { + _expression_mangling(v, map); + } + } + + Statement::Return(v) => { + if let Some(v) = v { + _expression_mangling(v, map); + } + } + + _ => {} + } + } + } + } + fn _mangling(codes: &mut Vec, suffix: &str, map: &mut HashMap) { for code in codes.iter_mut() { match code { @@ -1291,8 +1368,14 @@ impl CodeBlock { v.borrow_mut().name = new_name.clone(); map.insert(raw_name, new_name); + _mangling_block(&mut v.borrow_mut().body, map); } + Code::ShareVariable(v) => { + if v.borrow().modif.contains(&Modifier::Const) { + return; + } + let raw_name = v.borrow().name.clone(); let new_name = format!("{}_{}", raw_name, suffix);