gfx.rs 46 KB

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