gfx.rs 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256
  1. use darkfi_serial::{Decodable, Encodable, SerialDecodable, SerialEncodable};
  2. use freetype as ft;
  3. use miniquad::{
  4. conf, window, Backend, Bindings, BlendFactor, BlendState, BlendValue, BufferId, BufferLayout,
  5. BufferSource, BufferType, BufferUsage, Equation, EventHandler, KeyCode, KeyMods, MouseButton,
  6. PassAction, Pipeline, PipelineParams, RenderingBackend, ShaderMeta, ShaderSource, TextureId,
  7. UniformDesc, UniformType, VertexAttribute, VertexFormat,
  8. };
  9. use std::{
  10. array::IntoIter,
  11. fmt,
  12. io::Cursor,
  13. sync::{mpsc, Arc, MutexGuard},
  14. time::{Duration, Instant},
  15. };
  16. use crate::{
  17. error::{Error, Result},
  18. editbox,
  19. expr::{SExprMachine, SExprVal},
  20. keysym::MouseButtonAsU8,
  21. prop::{Property, PropertySubType, PropertyType},
  22. res::{ResourceId, ResourceManager},
  23. scene::{
  24. MethodResponseFn, SceneGraph, SceneGraphPtr, SceneNode, SceneNodeId, SceneNodeInfo,
  25. SceneNodeType, Pimpl
  26. },
  27. shader,
  28. };
  29. type Color = [f32; 4];
  30. pub const COLOR_RED: Color = [1., 0., 0., 1.];
  31. pub const COLOR_GREEN: Color = [0., 1., 0., 1.];
  32. pub const COLOR_BLUE: Color = [0., 0., 1., 1.];
  33. pub const COLOR_WHITE: Color = [1., 1., 1., 1.];
  34. #[derive(Debug, SerialEncodable, SerialDecodable)]
  35. #[repr(C)]
  36. struct Vertex {
  37. pos: [f32; 2],
  38. color: [f32; 4],
  39. uv: [f32; 2],
  40. }
  41. #[derive(SerialEncodable, SerialDecodable)]
  42. #[repr(C)]
  43. struct Face {
  44. idxs: [u32; 3],
  45. }
  46. impl fmt::Debug for Face {
  47. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  48. write!(f, "{:?}", self.idxs)
  49. }
  50. }
  51. struct Mesh {
  52. pub verts: Vec<Vertex>,
  53. pub faces: Vec<Face>,
  54. pub vertex_buffer: BufferId,
  55. pub index_buffer: BufferId,
  56. }
  57. pub struct Point<T> {
  58. pub x: T,
  59. pub y: T,
  60. }
  61. #[derive(Debug, Clone)]
  62. pub struct Rectangle<T: Copy + std::ops::Add<Output=T> + std::ops::Sub<Output=T> + std::cmp::PartialOrd> {
  63. pub x: T,
  64. pub y: T,
  65. pub w: T,
  66. pub h: T,
  67. }
  68. impl<T: Copy + std::ops::Add<Output=T> + std::ops::Sub<Output=T> + std::ops::AddAssign + std::cmp::PartialOrd> Rectangle<T> {
  69. fn from_array(arr: [T; 4]) -> Self {
  70. let mut iter = IntoIter::new(arr);
  71. Self {
  72. x: iter.next().unwrap(),
  73. y: iter.next().unwrap(),
  74. w: iter.next().unwrap(),
  75. h: iter.next().unwrap(),
  76. }
  77. }
  78. pub fn clip(&self, other: &Self) -> Option<Self> {
  79. if other.x + other.w < self.x ||
  80. other.x > self.x + self.w ||
  81. other.y + other.h < self.y ||
  82. other.y > self.y + self.h
  83. {
  84. return None
  85. }
  86. let mut clipped = other.clone();
  87. if clipped.x < self.x {
  88. clipped.x = self.x;
  89. }
  90. if clipped.y < self.y {
  91. clipped.y = self.y;
  92. }
  93. if clipped.x + clipped.w > self.x + self.w {
  94. clipped.w = self.x + self.w - clipped.x;
  95. }
  96. if clipped.y + clipped.h > self.y + self.h {
  97. clipped.h = self.y + self.h - clipped.y;
  98. }
  99. Some(clipped)
  100. }
  101. pub fn contains(&self, point: &Point<T>) -> bool {
  102. self.x < point.x && point.x < self.x + self.w &&
  103. self.y < point.y && point.y < self.y + self.h
  104. }
  105. }
  106. pub type FreetypeFace = ft::Face<&'static [u8]>;
  107. #[derive(Debug)]
  108. enum GraphicsMethodEvent {
  109. LoadTexture,
  110. DeleteTexture,
  111. CreateEditBox,
  112. }
  113. struct Stage {
  114. ctx: Box<dyn RenderingBackend>,
  115. pipeline: Pipeline,
  116. scene_graph: SceneGraphPtr,
  117. textures: ResourceManager<TextureId>,
  118. font_faces: Vec<FreetypeFace>,
  119. method_recvr: mpsc::Receiver<(GraphicsMethodEvent, SceneNodeId, Vec<u8>, MethodResponseFn)>,
  120. method_sender: mpsc::SyncSender<(GraphicsMethodEvent, SceneNodeId, Vec<u8>, MethodResponseFn)>,
  121. last_draw_time: Option<Instant>,
  122. }
  123. impl Stage {
  124. const WHITE_TEXTURE_ID: ResourceId = 0;
  125. pub fn new(scene_graph: SceneGraphPtr) -> Self {
  126. let mut ctx: Box<dyn RenderingBackend> = window::new_rendering_backend();
  127. let white_texture = ctx.new_texture_from_rgba8(1, 1, &[255, 255, 255, 255]);
  128. let mut textures = ResourceManager::new();
  129. let white_texture_id = textures.alloc(white_texture);
  130. assert_eq!(white_texture_id, Self::WHITE_TEXTURE_ID);
  131. let mut shader_meta: ShaderMeta = shader::meta();
  132. shader_meta.uniforms.uniforms.push(UniformDesc::new("Projection", UniformType::Mat4));
  133. shader_meta.uniforms.uniforms.push(UniformDesc::new("Model", UniformType::Mat4));
  134. let shader = ctx
  135. .new_shader(
  136. match ctx.info().backend {
  137. Backend::OpenGl => ShaderSource::Glsl {
  138. vertex: shader::GL_VERTEX,
  139. fragment: shader::GL_FRAGMENT,
  140. },
  141. Backend::Metal => ShaderSource::Msl { program: shader::METAL },
  142. },
  143. shader_meta,
  144. )
  145. .unwrap();
  146. let params = PipelineParams {
  147. color_blend: Some(BlendState::new(
  148. Equation::Add,
  149. BlendFactor::Value(BlendValue::SourceAlpha),
  150. BlendFactor::OneMinusValue(BlendValue::SourceAlpha),
  151. )),
  152. ..Default::default()
  153. };
  154. let pipeline = ctx.new_pipeline(
  155. &[BufferLayout::default()],
  156. &[
  157. VertexAttribute::new("in_pos", VertexFormat::Float2),
  158. VertexAttribute::new("in_color", VertexFormat::Float4),
  159. VertexAttribute::new("in_uv", VertexFormat::Float2),
  160. ],
  161. shader,
  162. params,
  163. );
  164. let (method_sender, method_recvr) = mpsc::sync_channel(100);
  165. let ftlib = ft::Library::init().unwrap();
  166. let mut font_faces = vec![];
  167. let font_data = include_bytes!("../Inter-Regular.otf") as &[u8];
  168. let ft_face = ftlib.new_memory_face2(font_data, 0).unwrap();
  169. font_faces.push(ft_face);
  170. let font_data = include_bytes!("../NotoColorEmoji.ttf") as &[u8];
  171. let ft_face = ftlib.new_memory_face2(font_data, 0).unwrap();
  172. font_faces.push(ft_face);
  173. let mut stage = Stage {
  174. ctx,
  175. pipeline,
  176. scene_graph,
  177. textures,
  178. font_faces,
  179. method_recvr,
  180. method_sender,
  181. last_draw_time: None,
  182. };
  183. stage.setup_scene_graph_window();
  184. debug!("Finished loading GUI");
  185. stage
  186. }
  187. fn setup_scene_graph_window(&mut self) {
  188. let mut scene_graph = self.scene_graph.lock().unwrap();
  189. let window = scene_graph.add_node("window", SceneNodeType::Window);
  190. let (screen_width, screen_height) = window::screen_size();
  191. let mut prop = Property::new("screen_size", PropertyType::Float32, PropertySubType::Pixel);
  192. prop.set_array_len(2);
  193. prop.set_f32(0, screen_width);
  194. prop.set_f32(1, screen_height);
  195. window.add_property(prop).unwrap();
  196. window
  197. .add_signal(
  198. "resize",
  199. "Screen resize event",
  200. vec![
  201. ("screen_width", "", PropertyType::Float32),
  202. ("screen_height", "", PropertyType::Float32),
  203. ],
  204. )
  205. .unwrap();
  206. let window_id = window.id;
  207. let sender = self.method_sender.clone();
  208. let method_fn = Box::new(move |arg_data, response_fn| {
  209. sender.send((GraphicsMethodEvent::LoadTexture, window_id, arg_data, response_fn));
  210. });
  211. window
  212. .add_method(
  213. "load_texture",
  214. vec![("node_name", "", PropertyType::Str), ("path", "", PropertyType::Str)],
  215. vec![("node_id", "", PropertyType::SceneNodeId)],
  216. method_fn,
  217. )
  218. .unwrap();
  219. let sender = self.method_sender.clone();
  220. let method_fn = Box::new(move |arg_data, response_fn| {
  221. sender.send((GraphicsMethodEvent::CreateEditBox, window_id, arg_data, response_fn));
  222. });
  223. window
  224. .add_method(
  225. "create_edit_box",
  226. vec![("node_id", "", PropertyType::SceneNodeId)],
  227. vec![],
  228. method_fn,
  229. )
  230. .unwrap();
  231. scene_graph.link(window_id, SceneGraph::ROOT_ID).unwrap();
  232. let input = scene_graph.add_node("input", SceneNodeType::WindowInput);
  233. let input_id = input.id;
  234. scene_graph.link(input_id, window_id).unwrap();
  235. let keyb = scene_graph.add_node("keyboard", SceneNodeType::Keyboard);
  236. keyb.add_signal(
  237. "key_down",
  238. "Key press down event",
  239. vec![
  240. ("shift", "", PropertyType::Bool),
  241. ("ctrl", "", PropertyType::Bool),
  242. ("alt", "", PropertyType::Bool),
  243. ("logo", "", PropertyType::Bool),
  244. ("repeat", "", PropertyType::Bool),
  245. ("keycode", "", PropertyType::Enum),
  246. ],
  247. )
  248. .unwrap();
  249. let keyb_id = keyb.id;
  250. scene_graph.link(keyb_id, input_id).unwrap();
  251. let mouse = scene_graph.add_node("mouse", SceneNodeType::Mouse);
  252. mouse
  253. .add_signal(
  254. "button_up",
  255. "Mouse button up event",
  256. vec![
  257. ("button", "", PropertyType::Enum),
  258. ("x", "", PropertyType::Float32),
  259. ("y", "", PropertyType::Float32),
  260. ],
  261. )
  262. .unwrap();
  263. mouse
  264. .add_signal(
  265. "button_down",
  266. "Mouse button down event",
  267. vec![
  268. ("button", "", PropertyType::Enum),
  269. ("x", "", PropertyType::Float32),
  270. ("y", "", PropertyType::Float32),
  271. ],
  272. )
  273. .unwrap();
  274. mouse
  275. .add_signal(
  276. "wheel",
  277. "Mouse wheel scroll event",
  278. vec![("x", "", PropertyType::Float32), ("y", "", PropertyType::Float32)],
  279. )
  280. .unwrap();
  281. mouse
  282. .add_signal(
  283. "move",
  284. "Mouse cursor move event",
  285. vec![("x", "", PropertyType::Float32), ("y", "", PropertyType::Float32)],
  286. )
  287. .unwrap();
  288. let mouse_id = mouse.id;
  289. scene_graph.link(mouse_id, input_id).unwrap();
  290. }
  291. fn method_load_texture(&mut self, node_id: SceneNodeId, arg_data: Vec<u8>) -> Result<Vec<u8>> {
  292. let mut cur = Cursor::new(&arg_data);
  293. let node_name = String::decode(&mut cur).unwrap();
  294. let filepath = String::decode(&mut cur).unwrap();
  295. let Ok(img) = image::open(filepath) else { return Err(Error::FileNotFound) };
  296. let img = img.to_rgba8();
  297. let width = img.width();
  298. let height = img.height();
  299. let bmp = img.into_raw();
  300. let texture = self.ctx.new_texture_from_rgba8(width as u16, height as u16, &bmp);
  301. let id = self.textures.alloc(texture);
  302. let mut scene_graph = self.scene_graph.lock().unwrap();
  303. let img_node = scene_graph.add_node(node_name, SceneNodeType::RenderTexture);
  304. let mut prop = Property::new("size", PropertyType::Uint32, PropertySubType::Pixel);
  305. prop.set_array_len(2);
  306. prop.set_u32(0, width).unwrap();
  307. prop.set_u32(1, height).unwrap();
  308. img_node.add_property(prop)?;
  309. let mut prop =
  310. Property::new("texture_rid", PropertyType::Uint32, PropertySubType::ResourceId);
  311. prop.set_u32(0, id).unwrap();
  312. img_node.add_property(prop)?;
  313. let mut reply = vec![];
  314. img_node.id.encode(&mut reply).unwrap();
  315. Ok(reply)
  316. }
  317. fn method_delete_texture(
  318. &mut self,
  319. node_id: SceneNodeId,
  320. arg_data: Vec<u8>,
  321. ) -> Result<Vec<u8>> {
  322. let mut cur = Cursor::new(&arg_data);
  323. let texture_id = ResourceId::decode(&mut cur).unwrap();
  324. let texture = self.textures.get(texture_id).ok_or(Error::ResourceNotFound)?;
  325. self.ctx.delete_texture(*texture);
  326. self.textures.free(texture_id);
  327. Ok(vec![])
  328. }
  329. fn method_create_editbox(
  330. &mut self,
  331. _: SceneNodeId,
  332. arg_data: Vec<u8>,
  333. ) -> Result<Vec<u8>> {
  334. let mut cur = Cursor::new(&arg_data);
  335. let node_id = SceneNodeId::decode(&mut cur).unwrap();
  336. let mut scene_graph = self.scene_graph.lock().unwrap();
  337. let editbox = editbox::EditBox::new(&mut scene_graph, node_id, self.font_faces.clone())?;
  338. let node = scene_graph.get_node_mut(node_id).ok_or(Error::NodeNotFound)?;
  339. node.pimpl = editbox;
  340. let mut reply = vec![];
  341. Ok(reply)
  342. }
  343. }
  344. pub struct RenderContext<'a> {
  345. pub scene_graph: MutexGuard<'a, SceneGraph>,
  346. pub ctx: &'a mut Box<dyn RenderingBackend>,
  347. pub pipeline: &'a Pipeline,
  348. pub proj: glam::Mat4,
  349. pub textures: &'a ResourceManager<TextureId>,
  350. pub font_faces: &'a Vec<FreetypeFace>,
  351. }
  352. impl<'a> RenderContext<'a> {
  353. fn render_window(&mut self) {
  354. for layer in self
  355. .scene_graph
  356. .lookup_node("/window")
  357. .expect("no window attached!")
  358. .get_children(&[SceneNodeType::RenderLayer])
  359. {
  360. if let Err(err) = self.render_layer(layer.id) {
  361. error!("error rendering layer '{}': {}", layer.name, err)
  362. }
  363. }
  364. self.ctx.commit_frame();
  365. }
  366. fn get_rect(layer: &SceneNode) -> Result<Rectangle<i32>> {
  367. let prop = layer.get_property("rect").ok_or(Error::PropertyNotFound)?;
  368. if prop.array_len != 4 {
  369. return Err(Error::PropertyWrongLen)
  370. }
  371. let mut rect = [0; 4];
  372. for i in 0..4 {
  373. if prop.is_expr(i)? {
  374. let (screen_width, screen_height) = window::screen_size();
  375. let expr = prop.get_expr(i).unwrap();
  376. let machine = SExprMachine {
  377. globals: vec![
  378. ("sw".to_string(), SExprVal::Float32(screen_width)),
  379. ("sh".to_string(), SExprVal::Float32(screen_height)),
  380. ],
  381. stmts: &expr,
  382. };
  383. rect[i] = machine.call()?.as_u32()? as i32;
  384. } else {
  385. rect[i] = prop.get_u32(i)? as i32;
  386. }
  387. }
  388. Ok(Rectangle::from_array(rect))
  389. }
  390. fn render_layer(
  391. &mut self,
  392. layer_id: SceneNodeId,
  393. // parent rect
  394. ) -> Result<()> {
  395. let layer = self.scene_graph.get_node(layer_id).unwrap();
  396. if !layer.get_property_bool("is_visible")? {
  397. return Ok(())
  398. }
  399. self.ctx.begin_default_pass(PassAction::Nothing);
  400. self.ctx.apply_pipeline(&self.pipeline);
  401. let (_, screen_height) = window::screen_size();
  402. let rect = Self::get_rect(&layer)?;
  403. let mut view = rect.clone();
  404. view.y = screen_height as i32 - (rect.y + rect.h);
  405. self.ctx.apply_viewport(view.x, view.y, view.w, view.h);
  406. self.ctx.apply_scissor_rect(view.x, view.y, view.w, view.h);
  407. let rect = Rectangle {
  408. x: rect.x as f32,
  409. y: rect.y as f32,
  410. w: rect.w as f32,
  411. h: rect.h as f32,
  412. };
  413. let layer_children =
  414. layer.get_children(&[SceneNodeType::RenderMesh, SceneNodeType::RenderText, SceneNodeType::EditBox]);
  415. let layer_children = self.order_by_z_index(layer_children);
  416. // get the rectangle
  417. // make sure it's inside the parent's rect
  418. for child in layer_children {
  419. // x, y, w, h as pixels
  420. // note that (x, y) is offset by layer rect so it is the pos within layer
  421. // layer coords are (0, 0) -> (1, 1)
  422. // optionally evaluated using sexpr
  423. // mesh data is (0, 0) to (1, 1)
  424. // so scale by (w, h)
  425. match child.typ {
  426. SceneNodeType::RenderMesh => {
  427. if let Err(err) = self.render_mesh(child.id, &rect) {
  428. error!("error rendering mesh '{}': {}", child.name, err);
  429. }
  430. }
  431. SceneNodeType::RenderText => {
  432. if let Err(err) = self.render_text(child.id, &rect) {
  433. error!("error rendering text '{}': {}", child.name, err);
  434. }
  435. }
  436. SceneNodeType::EditBox => {
  437. let node = self.scene_graph.get_node(child.id).unwrap();
  438. let editbox = match &node.pimpl {
  439. Pimpl::EditBox(e) => e.clone(),
  440. _ => panic!("wrong pimpl for editbox")
  441. };
  442. if let Err(err) = editbox.render(self, child.id, &rect) {
  443. error!("error rendering editbox '{}': {}", child.name, err);
  444. }
  445. }
  446. _ => panic!("render_layer(): unknown type"),
  447. }
  448. }
  449. Ok(())
  450. }
  451. fn order_by_z_index(&self, nodes: Vec<SceneNodeInfo>) -> Vec<SceneNodeInfo> {
  452. let mut nodes: Vec<_> = nodes
  453. .into_iter()
  454. .filter_map(|node_inf| {
  455. let node = self.scene_graph.get_node(node_inf.id).unwrap();
  456. let z_index = node.get_property_u32("z_index").ok()?;
  457. Some((z_index, node_inf))
  458. })
  459. .collect();
  460. nodes.sort_unstable_by_key(|(z_index, node_inf)| *z_index);
  461. nodes.into_iter().map(|(z_index, node_inf)| node_inf).collect()
  462. }
  463. pub fn get_dim(mesh: &SceneNode, layer_rect: &Rectangle<f32>) -> Result<Rectangle<f32>> {
  464. let prop = mesh.get_property("rect").ok_or(Error::PropertyNotFound)?;
  465. if prop.array_len != 4 {
  466. return Err(Error::PropertyWrongLen)
  467. }
  468. let mut rect = [0.; 4];
  469. for i in 0..4 {
  470. if prop.is_expr(i)? {
  471. let expr = prop.get_expr(i).unwrap();
  472. let machine = SExprMachine {
  473. globals: vec![
  474. ("lw".to_string(), SExprVal::Uint32(layer_rect.w as u32)),
  475. ("lh".to_string(), SExprVal::Uint32(layer_rect.h as u32)),
  476. ],
  477. stmts: &expr,
  478. };
  479. rect[i] = machine.call()?.coerce_f32()?;
  480. } else {
  481. rect[i] = prop.get_f32(i)?;
  482. }
  483. }
  484. Ok(Rectangle::from_array(rect))
  485. }
  486. fn render_mesh(&mut self, node_id: SceneNodeId, layer_rect: &Rectangle<f32>) -> Result<()> {
  487. let mesh = self.scene_graph.get_node(node_id).unwrap();
  488. let z_index = mesh.get_property_u32("z_index")?;
  489. let data = mesh.get_property("data").ok_or(Error::PropertyNotFound)?;
  490. let verts = data.get_buf(0)?;
  491. let faces = data.get_buf(1)?;
  492. let vertex_buffer = self.ctx.new_buffer(
  493. BufferType::VertexBuffer,
  494. BufferUsage::Immutable,
  495. BufferSource::slice(&verts),
  496. );
  497. let bufsrc = unsafe {
  498. BufferSource::pointer(
  499. faces.as_ptr() as _,
  500. std::mem::size_of_val(&faces[..]),
  501. std::mem::size_of::<u32>(),
  502. )
  503. };
  504. let index_buffer =
  505. self.ctx.new_buffer(BufferType::IndexBuffer, BufferUsage::Immutable, bufsrc);
  506. // temp
  507. let texture = self.textures.get(Stage::WHITE_TEXTURE_ID).unwrap();
  508. let rect = Self::get_dim(mesh, layer_rect)?;
  509. //debug!("mesh rect: {:?}", rect);
  510. let layer_w = layer_rect.w as f32;
  511. let layer_h = layer_rect.h as f32;
  512. let off_x = rect.x / layer_w;
  513. let off_y = rect.y / layer_h;
  514. let scale_x = rect.w / layer_w;
  515. let scale_y = rect.h / layer_h;
  516. //let model = glam::Mat4::IDENTITY;
  517. let model = glam::Mat4::from_translation(glam::Vec3::new(off_x, off_y, 0.)) *
  518. glam::Mat4::from_scale(glam::Vec3::new(scale_x, scale_y, 1.));
  519. let mut uniforms_data = [0u8; 128];
  520. let data: [u8; 64] = unsafe { std::mem::transmute_copy(&self.proj) };
  521. uniforms_data[0..64].copy_from_slice(&data);
  522. let data: [u8; 64] = unsafe { std::mem::transmute_copy(&model) };
  523. uniforms_data[64..].copy_from_slice(&data);
  524. assert_eq!(128, 2 * UniformType::Mat4.size());
  525. let bindings =
  526. Bindings { vertex_buffers: vec![vertex_buffer], index_buffer, images: vec![*texture] };
  527. self.ctx.apply_bindings(&bindings);
  528. self.ctx.apply_uniforms_from_bytes(uniforms_data.as_ptr(), uniforms_data.len());
  529. self.ctx.draw(0, 3 * faces.len() as i32, 1);
  530. self.ctx.delete_buffer(index_buffer);
  531. self.ctx.delete_buffer(vertex_buffer);
  532. Ok(())
  533. }
  534. pub fn render_clipped_box_with_texture(
  535. &mut self,
  536. bound_rect: &Rectangle<f32>,
  537. x1: f32,
  538. y1: f32,
  539. x2: f32,
  540. y2: f32,
  541. color: Color,
  542. texture: TextureId,
  543. ) {
  544. let obj = Rectangle {
  545. x: x1,
  546. y: y1,
  547. w: x2 - x1,
  548. h: y2 - y1
  549. };
  550. let Some(clipped) = bound_rect.clip(&obj) else {
  551. return
  552. };
  553. let x1 = clipped.x;
  554. let y1 = clipped.y;
  555. let x2 = clipped.x + clipped.w;
  556. let y2 = clipped.y + clipped.h;
  557. let u1 = (clipped.x - obj.x) / obj.w;
  558. let u2 = (clipped.x + clipped.w - obj.x) / obj.w + u1;
  559. let v1 = (clipped.y - obj.y) / obj.h;
  560. let v2 = (clipped.y + clipped.h - obj.y) / obj.h + v1;
  561. let vertices: [Vertex; 4] = [
  562. // top left
  563. Vertex { pos: [x1, y1], color, uv: [u1, v1] },
  564. // top right
  565. Vertex { pos: [x2, y1], color, uv: [u2, v1] },
  566. // bottom left
  567. Vertex { pos: [x1, y2], color, uv: [u1, v2] },
  568. // bottom right
  569. Vertex { pos: [x2, y2], color, uv: [u2, v2] },
  570. ];
  571. //debug!("screen size: {:?}", window::screen_size());
  572. let vertex_buffer = self.ctx.new_buffer(
  573. BufferType::VertexBuffer,
  574. BufferUsage::Immutable,
  575. BufferSource::slice(&vertices),
  576. );
  577. let indices: [u16; 6] = [0, 2, 1, 1, 2, 3];
  578. let index_buffer = self.ctx.new_buffer(
  579. BufferType::IndexBuffer,
  580. BufferUsage::Immutable,
  581. BufferSource::slice(&indices),
  582. );
  583. let bindings =
  584. Bindings { vertex_buffers: vec![vertex_buffer], index_buffer, images: vec![texture] };
  585. self.ctx.apply_bindings(&bindings);
  586. self.ctx.draw(0, 6, 1);
  587. }
  588. pub fn render_box_with_texture(
  589. &mut self,
  590. x1: f32,
  591. y1: f32,
  592. x2: f32,
  593. y2: f32,
  594. color: Color,
  595. texture: TextureId,
  596. ) {
  597. let vertices: [Vertex; 4] = [
  598. // top left
  599. Vertex { pos: [x1, y1], color, uv: [0., 0.] },
  600. // top right
  601. Vertex { pos: [x2, y1], color, uv: [1., 0.] },
  602. // bottom left
  603. Vertex { pos: [x1, y2], color, uv: [0., 1.] },
  604. // bottom right
  605. Vertex { pos: [x2, y2], color, uv: [1., 1.] },
  606. ];
  607. //debug!("screen size: {:?}", window::screen_size());
  608. let vertex_buffer = self.ctx.new_buffer(
  609. BufferType::VertexBuffer,
  610. BufferUsage::Immutable,
  611. BufferSource::slice(&vertices),
  612. );
  613. let indices: [u16; 6] = [0, 2, 1, 1, 2, 3];
  614. let index_buffer = self.ctx.new_buffer(
  615. BufferType::IndexBuffer,
  616. BufferUsage::Immutable,
  617. BufferSource::slice(&indices),
  618. );
  619. let bindings =
  620. Bindings { vertex_buffers: vec![vertex_buffer], index_buffer, images: vec![texture] };
  621. self.ctx.apply_bindings(&bindings);
  622. self.ctx.draw(0, 6, 1);
  623. }
  624. pub fn render_box(&mut self, x1: f32, y1: f32, x2: f32, y2: f32, color: Color) {
  625. let texture = self.textures.get(Stage::WHITE_TEXTURE_ID).unwrap();
  626. self.render_box_with_texture(x1, y1, x2, y2, color, *texture)
  627. }
  628. pub fn hline(&mut self, min_x: f32, max_x: f32, y: f32, color: Color, w: f32) {
  629. self.render_box(min_x, y - w / 2., max_x, y + w / 2., color)
  630. }
  631. pub fn vline(&mut self, x: f32, min_y: f32, max_y: f32, color: Color, w: f32) {
  632. self.render_box(x - w / 2., min_y, x + w / 2., max_y, color)
  633. }
  634. pub fn outline(&mut self, x1: f32, y1: f32, x2: f32, y2: f32, color: Color, w: f32) {
  635. // top
  636. self.render_box(x1, y1, x2, y1 + w, color);
  637. // left
  638. self.render_box(x1, y1, x1 + w, y2, color);
  639. // right
  640. self.render_box(x2 - w, y1, x2, y2, color);
  641. // bottom
  642. self.render_box(x1, y2 - w, x2, y2, color);
  643. }
  644. fn render_text(&mut self, node_id: SceneNodeId, layer_rect: &Rectangle<f32>) -> Result<()> {
  645. let node = self.scene_graph.get_node(node_id).unwrap();
  646. let text = node.get_property_str("text")?;
  647. let font_size = node.get_property_f32("font_size")?;
  648. let debug = node.get_property_bool("debug")?;
  649. let rect = Self::get_dim(node, layer_rect)?;
  650. let baseline = node.get_property_f32("baseline")?;
  651. let color_prop = node.get_property("color").ok_or(Error::PropertyNotFound)?;
  652. let color_r = color_prop.get_f32(0)?;
  653. let color_g = color_prop.get_f32(1)?;
  654. let color_b = color_prop.get_f32(2)?;
  655. let color_a = color_prop.get_f32(3)?;
  656. let layer_w = layer_rect.w as f32;
  657. let layer_h = layer_rect.h as f32;
  658. let off_x = rect.x / layer_w;
  659. let off_y = rect.y / layer_h;
  660. // Use absolute pixel scale
  661. let scale_x = 1. / layer_w;
  662. let scale_y = 1. / layer_h;
  663. //let model = glam::Mat4::IDENTITY;
  664. let model = glam::Mat4::from_translation(glam::Vec3::new(off_x, off_y, 0.)) *
  665. glam::Mat4::from_scale(glam::Vec3::new(scale_x, scale_y, 1.));
  666. let mut uniforms_data = [0u8; 128];
  667. let data: [u8; 64] = unsafe { std::mem::transmute_copy(&self.proj) };
  668. uniforms_data[0..64].copy_from_slice(&data);
  669. let data: [u8; 64] = unsafe { std::mem::transmute_copy(&model) };
  670. uniforms_data[64..].copy_from_slice(&data);
  671. assert_eq!(128, 2 * UniformType::Mat4.size());
  672. self.ctx.apply_uniforms_from_bytes(uniforms_data.as_ptr(), uniforms_data.len());
  673. //let mut strings = vec![];
  674. //let mut current_str = String::new();
  675. //let mut current_idx = 0;
  676. //for chr in text.chars() {
  677. // let ft_face = self.font_faces[current_idx];
  678. // if ft_face.get_char_index(chr as usize).is_some() {
  679. // }
  680. //}
  681. let mut current_idx = 0;
  682. let mut current_str = String::new();
  683. let mut substrs = vec![];
  684. 'next_char: for chr in text.chars() {
  685. let idx = 'get_idx: {
  686. for i in 0..self.font_faces.len() {
  687. let ft_face = &self.font_faces[i];
  688. if ft_face.get_char_index(chr as usize).is_some() {
  689. break 'get_idx i
  690. }
  691. }
  692. warn!("no font fallback for char: {}", chr);
  693. // Skip this char
  694. continue 'next_char
  695. };
  696. if current_idx != idx {
  697. if !current_str.is_empty() {
  698. // Push
  699. substrs.push((current_idx, current_str.clone()));
  700. }
  701. current_str.clear();
  702. current_idx = idx;
  703. }
  704. current_str.push(chr);
  705. }
  706. if !current_str.is_empty() {
  707. // Push
  708. substrs.push((current_idx, current_str));
  709. }
  710. let mut current_x = 0.;
  711. let mut current_y = baseline;
  712. for (face_idx, text) in substrs {
  713. let face = &self.font_faces[face_idx];
  714. if face.has_fixed_sizes() {
  715. // emojis required a fixed size
  716. //face.set_char_size(109 * 64, 0, 72, 72).unwrap();
  717. face.select_size(0).unwrap();
  718. } else {
  719. face.set_char_size(font_size as isize * 64, 0, 72, 72).unwrap();
  720. }
  721. let hb_font = harfbuzz_rs::Font::from_freetype_face(face.clone());
  722. let buffer = harfbuzz_rs::UnicodeBuffer::new().add_str(&text);
  723. let output = harfbuzz_rs::shape(&hb_font, buffer, &[]);
  724. let positions = output.get_glyph_positions();
  725. let infos = output.get_glyph_infos();
  726. for (position, info) in positions.iter().zip(infos) {
  727. let gid = info.codepoint;
  728. // Index within this substr
  729. // let cluster = info.cluster;
  730. let mut flags = ft::face::LoadFlag::DEFAULT;
  731. if face.has_color() {
  732. flags |= ft::face::LoadFlag::COLOR;
  733. }
  734. face.load_glyph(gid, flags).unwrap();
  735. let glyph = face.glyph();
  736. glyph.render_glyph(ft::RenderMode::Normal).unwrap();
  737. // https://gist.github.com/jokertarot/7583938?permalink_comment_id=3327566#gistcomment-3327566
  738. let bmp = glyph.bitmap();
  739. let buffer = bmp.buffer();
  740. let bmp_width = bmp.width() as usize;
  741. let bmp_height = bmp.rows() as usize;
  742. let bearing_x = glyph.bitmap_left() as f32;
  743. let bearing_y = glyph.bitmap_top() as f32;
  744. //assert_eq!(bmp.pixel_mode().unwrap(), ft::bitmap::PixelMode::Bgra);
  745. //assert_eq!(bmp.pixel_mode().unwrap(), ft::bitmap::PixelMode::Lcd);
  746. //assert_eq!(bmp.pixel_mode().unwrap(), ft::bitmap::PixelMode::Gray);
  747. let pixel_mode = bmp.pixel_mode().unwrap();
  748. let tdata = match pixel_mode {
  749. ft::bitmap::PixelMode::Bgra => {
  750. let mut tdata = vec![];
  751. tdata.resize(4 * bmp_width * bmp_height, 0);
  752. // Convert from BGRA to RGBA
  753. for i in 0..bmp_width*bmp_height as usize {
  754. let idx = i*4;
  755. let b = buffer[idx];
  756. let g = buffer[idx + 1];
  757. let r = buffer[idx + 2];
  758. let a = buffer[idx + 3];
  759. tdata[idx] = r;
  760. tdata[idx + 1] = g;
  761. tdata[idx + 2] = b;
  762. tdata[idx + 3] = a;
  763. }
  764. tdata
  765. }
  766. ft::bitmap::PixelMode::Gray => {
  767. // Convert from greyscale to RGBA8
  768. let tdata: Vec<_> = buffer
  769. .iter()
  770. .flat_map(|coverage| {
  771. let r = (255. * color_r) as u8;
  772. let g = (255. * color_g) as u8;
  773. let b = (255. * color_b) as u8;
  774. let α = ((*coverage as f32) * color_a) as u8;
  775. vec![r, g, b, α]
  776. })
  777. .collect();
  778. tdata
  779. }
  780. _ => panic!("unsupport pixel mode: {:?}", pixel_mode)
  781. };
  782. let (x1, y1, x2, y2) = if face.has_fixed_sizes() {
  783. // Downscale by height
  784. let width = (bmp_width as f32 * font_size) / bmp_height as f32;
  785. let height = font_size;
  786. let x1 = current_x;
  787. let y1 = current_y - height;
  788. let x2 = current_x + width;
  789. let y2 = current_y;
  790. current_x += width;
  791. (x1, y1, x2, y2)
  792. } else {
  793. let (width, height) = (bmp_width as f32, bmp_height as f32);
  794. let off_x = position.x_offset as f32 / 64.;
  795. let off_y = position.y_offset as f32 / 64.;
  796. let x1 = current_x + off_x + bearing_x;
  797. let y1 = current_y - off_y - bearing_y;
  798. let x2 = x1 + width as f32;
  799. let y2 = y1 + height as f32;
  800. let x_advance = position.x_advance as f32 / 64.;
  801. let y_advance = position.y_advance as f32 / 64.;
  802. current_x += x_advance;
  803. current_y += y_advance;
  804. (x1, y1, x2, y2)
  805. };
  806. let texture = self.ctx.new_texture_from_rgba8(bmp_width as u16, bmp_height as u16, &tdata);
  807. self.render_box_with_texture(x1, y1, x2, y2, COLOR_WHITE, texture);
  808. self.ctx.delete_texture(texture);
  809. if debug {
  810. self.outline(x1, y1, x2, y2, COLOR_BLUE, 1.);
  811. }
  812. }
  813. if debug {
  814. self.hline(0., current_x, 0., COLOR_RED, 1.);
  815. }
  816. }
  817. Ok(())
  818. }
  819. fn render_glyph(&mut self, glyph_id: u32, font_size: f32, x: f32, y: f32) -> Result<()> {
  820. Ok(())
  821. }
  822. }
  823. impl EventHandler for Stage {
  824. fn update(&mut self) {
  825. if self.last_draw_time.is_none() {
  826. return
  827. }
  828. // Only allow 20 ms, process as much as we can during that time
  829. let elapsed_since_draw = self.last_draw_time.unwrap().elapsed();
  830. // We're long overdue a redraw. Exit for now
  831. if elapsed_since_draw > Duration::from_millis(20) {
  832. return
  833. }
  834. // The next redraw must happen 20ms since its last one.
  835. // Calculate how much time is remaining until then.
  836. let allowed_time = Duration::from_millis(20) - elapsed_since_draw;
  837. let deadline = Instant::now() + allowed_time;
  838. loop {
  839. let Ok((event, node_id, arg_data, response_fn)) =
  840. self.method_recvr.recv_deadline(deadline)
  841. else {
  842. break
  843. };
  844. let res = match event {
  845. GraphicsMethodEvent::LoadTexture => self.method_load_texture(node_id, arg_data),
  846. GraphicsMethodEvent::DeleteTexture => self.method_delete_texture(node_id, arg_data),
  847. GraphicsMethodEvent::CreateEditBox => self.method_create_editbox(node_id, arg_data),
  848. };
  849. response_fn(res);
  850. }
  851. }
  852. // Only do drawing here. Apps might not call this when minimized.
  853. fn draw(&mut self) {
  854. self.last_draw_time = Some(Instant::now());
  855. let (screen_width, screen_height) = window::screen_size();
  856. // This will make the top left (0, 0) and the bottom right (1, 1)
  857. // Default is (-1, 1) -> (1, -1)
  858. let proj = glam::Mat4::from_translation(glam::Vec3::new(-1., 1., 0.)) *
  859. glam::Mat4::from_scale(glam::Vec3::new(2., -2., 1.));
  860. //let proj = glam::Mat4::IDENTITY;
  861. let scene_graph = self.scene_graph.lock().unwrap();
  862. // We need this because scene_graph must remain locked for the duration of the rendering
  863. let mut render_context = RenderContext {
  864. scene_graph,
  865. ctx: &mut self.ctx,
  866. pipeline: &self.pipeline,
  867. proj,
  868. textures: &self.textures,
  869. font_faces: &self.font_faces,
  870. };
  871. render_context.render_window();
  872. drop(render_context);
  873. }
  874. fn key_down_event(&mut self, keycode: KeyCode, modifiers: KeyMods, repeat: bool) {
  875. let mut scene_graph = self.scene_graph.lock().unwrap();
  876. let win = scene_graph.lookup_node_mut("/window/input/keyboard").unwrap();
  877. let send_key_down = |key: &str| {
  878. let mut data = vec![];
  879. modifiers.shift.encode(&mut data).unwrap();
  880. modifiers.ctrl.encode(&mut data).unwrap();
  881. modifiers.alt.encode(&mut data).unwrap();
  882. modifiers.logo.encode(&mut data).unwrap();
  883. repeat.encode(&mut data).unwrap();
  884. key.encode(&mut data).unwrap();
  885. win.trigger("key_down", data).unwrap();
  886. };
  887. match keycode {
  888. KeyCode::Space => send_key_down(" "),
  889. KeyCode::Apostrophe => send_key_down("'"),
  890. KeyCode::Comma => send_key_down(","),
  891. KeyCode::Minus => send_key_down("-"),
  892. KeyCode::Period => send_key_down("."),
  893. KeyCode::Slash => send_key_down("/"),
  894. KeyCode::Key0 => send_key_down("0"),
  895. KeyCode::Key1 => send_key_down("1"),
  896. KeyCode::Key2 => send_key_down("2"),
  897. KeyCode::Key3 => send_key_down("3"),
  898. KeyCode::Key4 => send_key_down("4"),
  899. KeyCode::Key5 => send_key_down("5"),
  900. KeyCode::Key6 => send_key_down("6"),
  901. KeyCode::Key7 => send_key_down("7"),
  902. KeyCode::Key8 => send_key_down("8"),
  903. KeyCode::Key9 => send_key_down("9"),
  904. KeyCode::Semicolon => send_key_down(":"),
  905. KeyCode::Equal => send_key_down("="),
  906. KeyCode::A => send_key_down("A"),
  907. KeyCode::B => send_key_down("B"),
  908. KeyCode::C => send_key_down("C"),
  909. KeyCode::D => send_key_down("D"),
  910. KeyCode::E => send_key_down("E"),
  911. KeyCode::F => send_key_down("F"),
  912. KeyCode::G => send_key_down("G"),
  913. KeyCode::H => send_key_down("H"),
  914. KeyCode::I => send_key_down("I"),
  915. KeyCode::J => send_key_down("J"),
  916. KeyCode::K => send_key_down("K"),
  917. KeyCode::L => send_key_down("L"),
  918. KeyCode::M => send_key_down("M"),
  919. KeyCode::N => send_key_down("N"),
  920. KeyCode::O => send_key_down("O"),
  921. KeyCode::P => send_key_down("P"),
  922. KeyCode::Q => send_key_down("Q"),
  923. KeyCode::R => send_key_down("R"),
  924. KeyCode::S => send_key_down("S"),
  925. KeyCode::T => send_key_down("T"),
  926. KeyCode::U => send_key_down("U"),
  927. KeyCode::V => send_key_down("V"),
  928. KeyCode::W => send_key_down("W"),
  929. KeyCode::X => send_key_down("X"),
  930. KeyCode::Y => send_key_down("Y"),
  931. KeyCode::Z => send_key_down("Z"),
  932. KeyCode::LeftBracket => send_key_down("("),
  933. KeyCode::Backslash => send_key_down("\\"),
  934. KeyCode::RightBracket => send_key_down(")"),
  935. KeyCode::GraveAccent => send_key_down("GraveAccent"),
  936. KeyCode::World1 => send_key_down("World1"),
  937. KeyCode::World2 => send_key_down("World2"),
  938. KeyCode::Escape => send_key_down("Escape"),
  939. KeyCode::Enter => send_key_down("Enter"),
  940. KeyCode::Tab => send_key_down("Tab"),
  941. KeyCode::Backspace => send_key_down("Backspace"),
  942. KeyCode::Insert => send_key_down("Insert"),
  943. KeyCode::Delete => send_key_down("Delete"),
  944. KeyCode::Right => send_key_down("Right"),
  945. KeyCode::Left => send_key_down("Left"),
  946. KeyCode::Down => send_key_down("Down"),
  947. KeyCode::Up => send_key_down("Up"),
  948. KeyCode::PageUp => send_key_down("PageUp"),
  949. KeyCode::PageDown => send_key_down("PageDown"),
  950. KeyCode::Home => send_key_down("Home"),
  951. KeyCode::End => send_key_down("End"),
  952. KeyCode::CapsLock => send_key_down("CapsLock"),
  953. KeyCode::ScrollLock => send_key_down("ScrollLock"),
  954. KeyCode::NumLock => send_key_down("NumLock"),
  955. KeyCode::PrintScreen => send_key_down("PrintScreen"),
  956. KeyCode::Pause => send_key_down("Pause"),
  957. KeyCode::F1 => send_key_down("F1"),
  958. KeyCode::F2 => send_key_down("F2"),
  959. KeyCode::F3 => send_key_down("F3"),
  960. KeyCode::F4 => send_key_down("F4"),
  961. KeyCode::F5 => send_key_down("F5"),
  962. KeyCode::F6 => send_key_down("F6"),
  963. KeyCode::F7 => send_key_down("F7"),
  964. KeyCode::F8 => send_key_down("F8"),
  965. KeyCode::F9 => send_key_down("F9"),
  966. KeyCode::F10 => send_key_down("F10"),
  967. KeyCode::F11 => send_key_down("F11"),
  968. KeyCode::F12 => send_key_down("F12"),
  969. KeyCode::F13 => send_key_down("F13"),
  970. KeyCode::F14 => send_key_down("F14"),
  971. KeyCode::F15 => send_key_down("F15"),
  972. KeyCode::F16 => send_key_down("F16"),
  973. KeyCode::F17 => send_key_down("F17"),
  974. KeyCode::F18 => send_key_down("F18"),
  975. KeyCode::F19 => send_key_down("F19"),
  976. KeyCode::F20 => send_key_down("F20"),
  977. KeyCode::F21 => send_key_down("F21"),
  978. KeyCode::F22 => send_key_down("F22"),
  979. KeyCode::F23 => send_key_down("F23"),
  980. KeyCode::F24 => send_key_down("F24"),
  981. KeyCode::F25 => send_key_down("F25"),
  982. KeyCode::Kp0 => send_key_down("Kp0"),
  983. KeyCode::Kp1 => send_key_down("Kp1"),
  984. KeyCode::Kp2 => send_key_down("Kp2"),
  985. KeyCode::Kp3 => send_key_down("Kp3"),
  986. KeyCode::Kp4 => send_key_down("Kp4"),
  987. KeyCode::Kp5 => send_key_down("Kp5"),
  988. KeyCode::Kp6 => send_key_down("Kp6"),
  989. KeyCode::Kp7 => send_key_down("Kp7"),
  990. KeyCode::Kp8 => send_key_down("Kp8"),
  991. KeyCode::Kp9 => send_key_down("Kp9"),
  992. KeyCode::KpDecimal => send_key_down("KpDecimal"),
  993. KeyCode::KpDivide => send_key_down("KpDivide"),
  994. KeyCode::KpMultiply => send_key_down("KpMultiply"),
  995. KeyCode::KpSubtract => send_key_down("KpSubtract"),
  996. KeyCode::KpAdd => send_key_down("KpAdd"),
  997. KeyCode::KpEnter => send_key_down("KpEnter"),
  998. KeyCode::KpEqual => send_key_down("KpEqual"),
  999. KeyCode::LeftShift => send_key_down("LeftShift"),
  1000. KeyCode::LeftControl => send_key_down("LeftControl"),
  1001. KeyCode::LeftAlt => send_key_down("LeftAlt"),
  1002. KeyCode::LeftSuper => send_key_down("LeftSuper"),
  1003. KeyCode::RightShift => send_key_down("RightShift"),
  1004. KeyCode::RightControl => send_key_down("RightControl"),
  1005. KeyCode::RightAlt => send_key_down("RightAlt"),
  1006. KeyCode::RightSuper => send_key_down("RightSuper"),
  1007. KeyCode::Menu => send_key_down("Menu"),
  1008. KeyCode::Unknown => send_key_down("Unknown"),
  1009. }
  1010. }
  1011. fn mouse_motion_event(&mut self, x: f32, y: f32) {
  1012. let mut scene_graph = self.scene_graph.lock().unwrap();
  1013. let mut data = vec![];
  1014. x.encode(&mut data).unwrap();
  1015. y.encode(&mut data).unwrap();
  1016. let mouse = scene_graph.lookup_node_mut("/window/input/mouse").unwrap();
  1017. mouse.trigger("move", data).unwrap();
  1018. }
  1019. fn mouse_wheel_event(&mut self, x: f32, y: f32) {
  1020. let mut scene_graph = self.scene_graph.lock().unwrap();
  1021. let mut data = vec![];
  1022. x.encode(&mut data).unwrap();
  1023. y.encode(&mut data).unwrap();
  1024. let mouse = scene_graph.lookup_node_mut("/window/input/mouse").unwrap();
  1025. mouse.trigger("wheel", data).unwrap();
  1026. }
  1027. fn mouse_button_down_event(&mut self, button: MouseButton, x: f32, y: f32) {
  1028. let mut scene_graph = self.scene_graph.lock().unwrap();
  1029. let mut data = vec![];
  1030. button.to_u8().encode(&mut data).unwrap();
  1031. x.encode(&mut data).unwrap();
  1032. y.encode(&mut data).unwrap();
  1033. let mouse = scene_graph.lookup_node_mut("/window/input/mouse").unwrap();
  1034. mouse.trigger("button_down", data).unwrap();
  1035. }
  1036. fn mouse_button_up_event(&mut self, button: MouseButton, x: f32, y: f32) {
  1037. let mut scene_graph = self.scene_graph.lock().unwrap();
  1038. let mut data = vec![];
  1039. button.to_u8().encode(&mut data).unwrap();
  1040. x.encode(&mut data).unwrap();
  1041. y.encode(&mut data).unwrap();
  1042. let mouse = scene_graph.lookup_node_mut("/window/input/mouse").unwrap();
  1043. mouse.trigger("button_up", data).unwrap();
  1044. }
  1045. fn resize_event(&mut self, width: f32, height: f32) {
  1046. let mut data = vec![];
  1047. width.encode(&mut data).unwrap();
  1048. height.encode(&mut data).unwrap();
  1049. let mut scene_graph = self.scene_graph.lock().unwrap();
  1050. let win = scene_graph.lookup_node_mut("/window").unwrap();
  1051. let prop = win.get_property("screen_size").unwrap();
  1052. prop.set_f32(0, width).unwrap();
  1053. prop.set_f32(1, height).unwrap();
  1054. win.trigger("resize", data).unwrap();
  1055. }
  1056. }
  1057. pub fn run_gui(scene_graph: SceneGraphPtr) {
  1058. #[cfg(target_os = "android")]
  1059. {
  1060. android_logger::init_once(
  1061. android_logger::Config::default().with_max_level(LevelFilter::Debug).with_tag("fagman"),
  1062. );
  1063. }
  1064. #[cfg(target_os = "linux")]
  1065. {
  1066. let term_logger = simplelog::TermLogger::new(
  1067. simplelog::LevelFilter::Debug,
  1068. simplelog::Config::default(),
  1069. simplelog::TerminalMode::Mixed,
  1070. simplelog::ColorChoice::Auto,
  1071. );
  1072. simplelog::CombinedLogger::init(vec![term_logger]).expect("logger");
  1073. }
  1074. let mut conf = miniquad::conf::Conf {
  1075. high_dpi: true,
  1076. window_resizable: true,
  1077. platform: miniquad::conf::Platform {
  1078. linux_backend: miniquad::conf::LinuxBackend::WaylandWithX11Fallback,
  1079. wayland_use_fallback_decorations: false,
  1080. ..Default::default()
  1081. },
  1082. ..Default::default()
  1083. };
  1084. let metal = std::env::args().nth(1).as_deref() == Some("metal");
  1085. conf.platform.apple_gfx_api =
  1086. if metal { conf::AppleGfxApi::Metal } else { conf::AppleGfxApi::OpenGl };
  1087. miniquad::start(conf, || Box::new(Stage::new(scene_graph)));
  1088. }