This commit is contained in:
tsuki 2024-07-10 23:48:28 +08:00
parent 8721daed30
commit 2fcff3c6d9
7 changed files with 193 additions and 42 deletions

View File

@ -53,34 +53,39 @@ impl Program {
self.set_hook("viewport", viewport.snippet()); 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 { unsafe {
let vertex_array = gl // let vertex_array = gl
.create_vertex_array() // .create_vertex_array()
.expect("Cannot 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 = 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 = 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); gl.link_program(program);
if !gl.get_program_link_status(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, vertex_shader);
gl.detach_shader(program, fragment_shader); gl.detach_shader(program, fragment_shader);
self.native_program = Some(program); self.native_program = Some(program);
} }
Ok(())
} }
fn create_shader( fn create_shader(
&self, &self,
gl: &glow::Context, gl: &glow::Context,
code: &str, code: &str,
version: &'static str,
shader_type: u32, shader_type: u32,
) -> <glow::Context as HasContext>::Shader { ) -> <glow::Context as HasContext>::Shader {
let shader = unsafe { let shader = unsafe {

View File

@ -27,7 +27,7 @@ impl std::fmt::Display for Shader {
impl Shader { impl Shader {
pub fn new<S: Borrow<str>>(target: ShaderType, code: CodeType<S>) -> Result<Self> { pub fn new<S: Borrow<str>>(target: ShaderType, code: CodeType<S>) -> Result<Self> {
let code = match code { let mut code = match code {
CodeType::Code(code) => code.borrow().to_string(), CodeType::Code(code) => code.borrow().to_string(),
CodeType::Path(path) => { CodeType::Path(path) => {
let code = find_file(path).expect("Failed to find file"); 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 code = merge_includes(code).map_err(|e| Error::InvalidSnippet(e.to_string()))?;
let parsed = CodeBlock::new(&code)?; let parsed = CodeBlock::new(&code)?;

View File

@ -6,4 +6,10 @@ pub type Result<T> = std::result::Result<T, Error>;
pub enum Error { pub enum Error {
#[error("Invalid Snippet {0}")] #[error("Invalid Snippet {0}")]
InvalidSnippet(String), InvalidSnippet(String),
#[error("Invalid Shader {0}")]
InvalidShader(String),
#[error("Invalid Program {0}")]
InvalidProgram(String),
} }

View File

@ -11,7 +11,7 @@ use crate::graphics::Graphics;
use super::Colletion; use super::Colletion;
struct AggFastPath { pub struct AggFastPath {
program: Program, program: Program,
buffer: Vec<Point>, buffer: Vec<Point>,
} }
@ -35,21 +35,23 @@ impl AggFastPath {
uniform float linewidth; uniform float linewidth;
unifrom float antialias; uniform float antialias;
uniform vec4 color; uniform vec4 color;
") ,false, None)?; ") ,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, "330 core");
let mut program = Program::new(vertex, fragment, None, "");
program.set_transform(transform); program.set_transform(transform);
program.set_viewport(viewport); program.set_viewport(viewport);
println!("{}", program.vertex());
println!("{}", program.fragment());
Ok(Self { Ok(Self {
program, program,
buffer: Vec::with_capacity(128), buffer: Vec::with_capacity(128),
@ -66,6 +68,12 @@ impl Colletion for AggFastPath {
} }
impl Graphics for AggFastPath { impl Graphics for AggFastPath {
fn compile(&mut self, gl: &glow::Context) -> Result<()> {
self.program.compile(gl)
}
fn draw(&self) -> Result<()> { fn draw(&self) -> Result<()> {
use bytemuck::cast_slice; use bytemuck::cast_slice;
@ -251,7 +259,5 @@ mod test {
let agg_path = AggFastPath::new(&transform, &viewport).unwrap(); let agg_path = AggFastPath::new(&transform, &viewport).unwrap();
} }
} }

View File

@ -9,4 +9,6 @@ pub use colormesh::ColorMesh;
pub trait Graphics { pub trait Graphics {
fn draw(&self) -> Result<()>; fn draw(&self) -> Result<()>;
fn compile(&mut self, gl: &glow::Context) -> Result<()>;
} }

View File

@ -1,5 +1,16 @@
use crate::utils::Triangler; use crate::camera::Camera;
use nalgebra_glm::perspective; 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::{ use glutin::{
config::ConfigTemplateBuilder, config::ConfigTemplateBuilder,
context::{ContextAttributesBuilder, NotCurrentGlContext, PossiblyCurrentContext}, context::{ContextAttributesBuilder, NotCurrentGlContext, PossiblyCurrentContext},
@ -7,18 +18,19 @@ use glutin::{
surface::{GlSurface, Surface, SurfaceAttributesBuilder, WindowSurface}, surface::{GlSurface, Surface, SurfaceAttributesBuilder, WindowSurface},
}; };
use imgui::Ui; use imgui::Ui;
use imgui_winit_support::{HiDpiMode, winit::{ use imgui_winit_support::{
dpi::{LogicalSize, PhysicalPosition}, winit::{
event_loop::EventLoop, dpi::{LogicalSize, PhysicalPosition},
window::{Window, WindowBuilder}, event_loop::EventLoop,
}, WinitPlatform}; window::{Window, WindowBuilder},
},
HiDpiMode, WinitPlatform,
};
use nalgebra_glm::perspective;
use nalgebra_glm::Vec3;
use raw_window_handle::HasRawWindowHandle; use raw_window_handle::HasRawWindowHandle;
use std::num::NonZeroU32; use std::num::NonZeroU32;
use std::time::Instant; use std::time::Instant;
use cgmath::InnerSpace;
use glow::HasContext;
use nalgebra_glm::Vec3;
use crate::camera::Camera;
pub fn init<FUi>(mut run_ui: FUi) pub fn init<FUi>(mut run_ui: FUi)
where where
@ -28,7 +40,6 @@ where
let (mut winit_platform, mut imgui_context) = imgui_init(&window); 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") { let dpi_mode = if let Ok(factor) = std::env::var("IMGUI_EXAMPLE_FORCE_DPI_FACTOR") {
// Allow forcing of HiDPI factor for debugging purposes // Allow forcing of HiDPI factor for debugging purposes
match factor.parse::<f64>() { match factor.parse::<f64>() {
@ -55,14 +66,26 @@ where
let mut last_frame = Instant::now(); let mut last_frame = Instant::now();
let tri_renderer = Triangler::new(ig_renderer.gl_context(), "#version 330"); 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 program = tri_renderer.program();
let mut camera = Camera::new( let mut camera = Camera::new(
Vec3::new(0.5, 0.5, 1.0), // Camera position (world location 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, 1.0, 0.0), // Upward vector
Vec3::new(0.0, 0.0, -1.0), // Look at vector Vec3::new(0.0, 0.0, -1.0), // Look at vector
); );
let mut last_position: Option<PhysicalPosition<f64>> = None; let mut last_position: Option<PhysicalPosition<f64>> = None;
let mut yaw = -90.0; let mut yaw = -90.0;
let mut pitch = 0.0; let mut pitch = 0.0;
@ -97,7 +120,8 @@ where
let loc = gl.get_uniform_location(program, "projection"); let loc = gl.get_uniform_location(program, "projection");
let size = window.inner_size(); 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()); gl.uniform_matrix_4_f32_slice(loc.as_ref(), false, projection.as_slice());
let loc = gl.get_uniform_location(program, "view"); let loc = gl.get_uniform_location(program, "view");
@ -112,7 +136,14 @@ where
if ui.is_mouse_pos_valid(ui.io().mouse_pos) { if ui.is_mouse_pos_valid(ui.io().mouse_pos) {
let mouse_pos = ui.io().mouse_pos; let mouse_pos = ui.io().mouse_pos;
if ui.is_mouse_dragging(imgui::MouseButton::Right) { 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() .unwrap()
} }
fn mouse_callback(last_position: &mut Option<PhysicalPosition<f64>>, current_position:PhysicalPosition<f64>, sensitivity: f64, pitch: &mut f64, yaw: &mut f64, camera: &mut Camera) { fn mouse_callback(
use cgmath::{Euler, Deg, Quaternion}; last_position: &mut Option<PhysicalPosition<f64>>,
current_position: PhysicalPosition<f64>,
sensitivity: f64,
pitch: &mut f64,
yaw: &mut f64,
camera: &mut Camera,
) {
use cgmath::{Deg, Euler, Quaternion};
let xpos = current_position.x; let xpos = current_position.x;
let ypos = current_position.y; let ypos = current_position.y;
@ -197,11 +235,7 @@ fn mouse_callback(last_position: &mut Option<PhysicalPosition<f64>>, current_pos
*pitch = -89.0; *pitch = -89.0;
} }
let euler_deg = Euler::new( let euler_deg = Euler::new(Deg(*pitch), Deg(*yaw), Deg(0.0));
Deg(*pitch),
Deg(*yaw),
Deg(0.0),
);
let c = Quaternion::from(euler_deg).normalize(); let c = Quaternion::from(euler_deg).normalize();

View File

@ -137,7 +137,7 @@ fn include(input: &str) -> IResult<&str, Include> {
)) ))
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone, PartialEq)]
pub enum Modifier { pub enum Modifier {
Const, Const,
Static, Static,
@ -1282,6 +1282,83 @@ impl CodeBlock {
pub fn mangling<S: AsRef<str>>(&mut self, suffix: S) -> HashMap<String, String> { pub fn mangling<S: AsRef<str>>(&mut self, suffix: S) -> HashMap<String, String> {
let mut map = HashMap::new(); let mut map = HashMap::new();
fn _expression_mangling(exp: &mut Expression, map: &HashMap<String, String>) {
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<String, String>) {
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<Code>, suffix: &str, map: &mut HashMap<String, String>) { fn _mangling(codes: &mut Vec<Code>, suffix: &str, map: &mut HashMap<String, String>) {
for code in codes.iter_mut() { for code in codes.iter_mut() {
match code { match code {
@ -1291,8 +1368,14 @@ impl CodeBlock {
v.borrow_mut().name = new_name.clone(); v.borrow_mut().name = new_name.clone();
map.insert(raw_name, new_name); map.insert(raw_name, new_name);
_mangling_block(&mut v.borrow_mut().body, map);
} }
Code::ShareVariable(v) => { Code::ShareVariable(v) => {
if v.borrow().modif.contains(&Modifier::Const) {
return;
}
let raw_name = v.borrow().name.clone(); let raw_name = v.borrow().name.clone();
let new_name = format!("{}_{}", raw_name, suffix); let new_name = format!("{}_{}", raw_name, suffix);