You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

659 lines
18 KiB

  1. #![allow(dead_code)]
  2. use std::cell::RefCell;
  3. use std::cmp::PartialEq;
  4. use std::collections::HashMap;
  5. use std::fmt::Display;
  6. use std::hash::{Hash, Hasher};
  7. use std::mem::size_of;
  8. use std::ops::Deref;
  9. use std::ptr::null;
  10. use std::rc::{Rc, Weak};
  11. use glc::{
  12. array_buffer::{ArrayBuffer, Target, Usage},
  13. error::Error as GlcError,
  14. misc::BindGuard,
  15. shader::{Program, Type},
  16. texture::{FilterMag, FilterMin, Target as TextureTarget, Texture, Wrap},
  17. vector::{Vector2f, Vector4f},
  18. vertex_array::{DataType, VertexArray},
  19. };
  20. use glyph_brush::{
  21. ab_glyph::{FontArc, FontVec},
  22. BrushAction, BrushError, FontId, GlyphBrush, GlyphBrushBuilder, GlyphVertex, OwnedSection,
  23. OwnedText, Rectangle,
  24. };
  25. use log::warn;
  26. use ordered_float::OrderedFloat;
  27. use specs::World;
  28. use crate::{misc::Vfs, Error};
  29. use super::super::misc::WorldHelper;
  30. /* TextManager */
  31. #[derive(Clone)]
  32. pub struct TextManager(Rc<RefCell<TextManagerInner>>);
  33. struct TextManagerInner {
  34. vfs: Vfs,
  35. program: Rc<Program>,
  36. fonts: HashMap<String, FontArc>,
  37. }
  38. impl TextManager {
  39. pub fn new(world: &World) -> Result<Self, Error> {
  40. let vfs = world.resource::<Vfs>()?.deref().clone();
  41. let program = world.load_program(vec![
  42. (Type::Vertex, "resources/shader/text.vert"),
  43. (Type::Fragment, "resources/shader/text.frag"),
  44. ])?;
  45. let program = Rc::new(program);
  46. Ok(Self(Rc::new(RefCell::new(TextManagerInner {
  47. vfs,
  48. program,
  49. fonts: HashMap::new(),
  50. }))))
  51. }
  52. pub fn create_cache(&self) -> Result<TextCache, Error> {
  53. TextCache::new(self)
  54. }
  55. pub fn font(&self, path: &str) -> Result<FontArc, Error> {
  56. if let Some(font) = self.0.borrow().fonts.get(path) {
  57. return Ok(font.clone());
  58. }
  59. let path = self.0.borrow().vfs.join(path)?;
  60. let mut data = Vec::new();
  61. path.open_file()?.read_to_end(&mut data)?;
  62. let font = FontVec::try_from_vec(data)?;
  63. let font = FontArc::new(font);
  64. {
  65. let mut this = self.0.borrow_mut();
  66. this.fonts.insert(path.filename(), font.clone());
  67. this.fonts.insert(path.as_str().to_owned(), font.clone());
  68. }
  69. Ok(font)
  70. }
  71. }
  72. /* TextCache */
  73. #[derive(Clone)]
  74. pub struct TextCache(Rc<RefCell<TextCacheInner>>);
  75. pub struct TextCacheInner {
  76. manager: TextManager,
  77. fonts: HashMap<String, FontId>,
  78. glyphs: Option<GlyphBrush<Vertex, Extra>>,
  79. texture: Rc<RefCell<Texture>>,
  80. texts: HashMap<usize, Weak<RefCell<TextInner>>>,
  81. text_ids: Vec<usize>,
  82. next_text_id: usize,
  83. update_counter: usize,
  84. update_requested: bool,
  85. }
  86. pub struct UpdateGuard(TextCache);
  87. impl TextCache {
  88. fn new(manager: &TextManager) -> Result<Self, Error> {
  89. let mut texture = Texture::new(TextureTarget::Texture2D)?;
  90. texture.set_filter(FilterMin::Linear, FilterMag::Linear)?;
  91. texture.set_wrap(Wrap::ClampToEdge, Wrap::ClampToEdge, Wrap::ClampToEdge)?;
  92. Ok(Self(Rc::new(RefCell::new(TextCacheInner {
  93. manager: manager.clone(),
  94. fonts: HashMap::new(),
  95. glyphs: None,
  96. texture: Rc::new(RefCell::new(texture)),
  97. texts: HashMap::new(),
  98. text_ids: Vec::new(),
  99. next_text_id: 0,
  100. update_counter: 0,
  101. update_requested: false,
  102. }))))
  103. }
  104. pub fn new_text(&self) -> TextBuilder {
  105. TextBuilder::new(self)
  106. }
  107. pub fn begin_update(&self) -> UpdateGuard {
  108. self.0.borrow_mut().update_counter += 1;
  109. UpdateGuard(self.clone())
  110. }
  111. fn end_update(&self) {
  112. let mut inner = self.0.borrow_mut();
  113. if inner.update_counter > 0 {
  114. inner.update_counter -= 1;
  115. }
  116. if inner.update_counter > 0 {
  117. return;
  118. }
  119. let update_requested = inner.update_requested;
  120. drop(inner);
  121. if update_requested {
  122. if let Err(err) = self.update() {
  123. warn!("Unable to update text cache: {}", err);
  124. }
  125. }
  126. }
  127. fn font(&self, path: &str) -> Result<FontId, Error> {
  128. let mut inner = self.0.borrow_mut();
  129. if let Some(id) = inner.fonts.get(path) {
  130. return Ok(*id);
  131. }
  132. let font = inner.manager.font(path)?;
  133. inner.add_font(font)
  134. }
  135. fn next_text_id(&self) -> usize {
  136. let mut inner = self.0.borrow_mut();
  137. if let Some(id) = inner.text_ids.pop() {
  138. return id;
  139. }
  140. let ret = inner.next_text_id;
  141. inner.next_text_id += 1;
  142. ret
  143. }
  144. fn add_text(&self, text: Weak<RefCell<TextInner>>) -> Result<(), Error> {
  145. let text_id = self.next_text_id();
  146. for section in &mut text.upgrade().unwrap().borrow_mut().sections {
  147. for t in &mut section.text {
  148. t.extra.text_id = text_id;
  149. }
  150. }
  151. self.0.borrow_mut().texts.insert(text_id, text);
  152. self.update()
  153. }
  154. fn update(&self) -> Result<(), Error> {
  155. let mut inner = self.0.borrow_mut();
  156. let inner = &mut *inner;
  157. if inner.update_counter > 0 {
  158. inner.update_requested = true;
  159. return Ok(());
  160. }
  161. /* remove droped texts */
  162. let texts = &mut inner.texts;
  163. let text_ids = &mut inner.text_ids;
  164. texts.retain(|id, t| {
  165. if t.strong_count() > 0 {
  166. true
  167. } else {
  168. text_ids.push(*id);
  169. false
  170. }
  171. });
  172. /* add sections to glyph queue */
  173. let glyphs = inner.glyphs.as_mut().unwrap();
  174. for text in texts.values_mut() {
  175. for section in text.upgrade().unwrap().borrow_mut().sections.iter_mut() {
  176. glyphs.queue(section.to_borrowed());
  177. }
  178. }
  179. /* process glyph queue */
  180. let action = loop {
  181. let glyphs = inner.glyphs.as_mut().unwrap();
  182. let texture = inner.texture.borrow();
  183. let ret = glyphs.process_queued(
  184. move |rect, data| update_texture(&*texture, rect, data),
  185. create_vertex,
  186. );
  187. match ret {
  188. Ok(action) => break action,
  189. Err(BrushError::TextureTooSmall { suggested, .. }) => {
  190. let new_size = glyphs.texture_dimensions();
  191. let new_size = resize_texture(suggested, Some(new_size))?;
  192. glyphs.resize_texture(new_size.0, new_size.1);
  193. }
  194. }
  195. };
  196. // upate vertex data
  197. if let BrushAction::Draw(vertices) = action {
  198. let mut map = Vec::<Vec<VertexData>>::new();
  199. map.resize_with(inner.next_text_id, Default::default);
  200. for vertex in vertices {
  201. map[vertex.text_id].push(vertex.data);
  202. }
  203. for (text_id, data) in map.into_iter().enumerate() {
  204. if data.is_empty() {
  205. continue;
  206. }
  207. inner
  208. .texts
  209. .get(&text_id)
  210. .unwrap()
  211. .upgrade()
  212. .unwrap()
  213. .borrow_mut()
  214. .update(data)?;
  215. }
  216. }
  217. inner.update_requested = false;
  218. Ok(())
  219. }
  220. }
  221. impl TextCacheInner {
  222. fn add_font(&mut self, font: FontArc) -> Result<FontId, Error> {
  223. let (id, size) = match self.glyphs.as_mut() {
  224. Some(glyphs) => (glyphs.add_font(font), None),
  225. None => {
  226. let glyphs = GlyphBrushBuilder::using_font(font)
  227. .draw_cache_position_tolerance(2.0)
  228. .build();
  229. let size = glyphs.texture_dimensions();
  230. self.glyphs = Some(glyphs);
  231. (FontId(0), Some(size))
  232. }
  233. };
  234. if let Some(size) = size {
  235. let texture = self.texture.borrow();
  236. let _guard = BindGuard::new(&*texture);
  237. let new_size = resize_texture(size, None)?;
  238. self.glyphs
  239. .as_mut()
  240. .unwrap()
  241. .resize_texture(new_size.0, new_size.1);
  242. }
  243. Ok(id)
  244. }
  245. }
  246. impl Drop for UpdateGuard {
  247. fn drop(&mut self) {
  248. self.0.end_update()
  249. }
  250. }
  251. fn resize_texture(new_size: (u32, u32), cur_size: Option<(u32, u32)>) -> Result<(u32, u32), Error> {
  252. let mut max_size = 0;
  253. gl::get_integer_v(gl::MAX_TEXTURE_SIZE, &mut max_size);
  254. let max_size = max_size as u32;
  255. let (w, h) = if let Some(cur_size) = cur_size {
  256. if (new_size.0 > max_size || new_size.1 > max_size)
  257. && (cur_size.0 < max_size || cur_size.1 < max_size)
  258. {
  259. (max_size, max_size)
  260. } else {
  261. new_size
  262. }
  263. } else {
  264. new_size
  265. };
  266. GlcError::checked(|| {
  267. gl::tex_image_2d(
  268. gl::TEXTURE_2D,
  269. 0,
  270. gl::RED as _,
  271. w as _,
  272. h as _,
  273. 0,
  274. gl::RED,
  275. gl::UNSIGNED_BYTE,
  276. null(),
  277. )
  278. })?;
  279. Ok(new_size)
  280. }
  281. fn update_texture(texture: &Texture, rect: Rectangle<u32>, data: &[u8]) {
  282. let ret = GlcError::checked(|| {
  283. gl::texture_sub_image_2d(
  284. texture.id(),
  285. 0,
  286. rect.min[0] as _,
  287. rect.min[1] as _,
  288. rect.width() as _,
  289. rect.height() as _,
  290. gl::RED,
  291. gl::UNSIGNED_BYTE,
  292. data.as_ptr() as _,
  293. )
  294. });
  295. if let Err(err) = ret {
  296. warn!("Unable to update text texture: {}", err);
  297. }
  298. }
  299. fn create_vertex(data: GlyphVertex<Extra>) -> Vertex {
  300. let pos_min = Vector2f::new(data.pixel_coords.min.x, data.pixel_coords.min.y);
  301. let pos_max = Vector2f::new(data.pixel_coords.max.x, data.pixel_coords.max.y);
  302. let tex_min = Vector2f::new(data.tex_coords.min.x, data.tex_coords.min.y);
  303. let tex_max = Vector2f::new(data.tex_coords.max.x, data.tex_coords.max.y);
  304. Vertex {
  305. text_id: data.extra.text_id,
  306. data: VertexData {
  307. pos_min,
  308. pos_max,
  309. tex_min,
  310. tex_max,
  311. color: data.extra.color,
  312. },
  313. }
  314. }
  315. /* TextBuilder */
  316. pub struct TextBuilder {
  317. cache: TextCache,
  318. items: Vec<BuilderItem>,
  319. }
  320. enum BuilderItem {
  321. Position(f32, f32),
  322. Color(Vector4f),
  323. Font(String),
  324. Text(String),
  325. Scale(f32),
  326. }
  327. impl TextBuilder {
  328. fn new(cache: &TextCache) -> Self {
  329. Self {
  330. cache: cache.clone(),
  331. items: Vec::new(),
  332. }
  333. }
  334. pub fn build(self) -> Result<Text, Error> {
  335. let mut sections = Vec::<OwnedSection<Extra>>::new();
  336. let mut scale = 20.0;
  337. let mut font_id = None;
  338. let mut color = Vector4f::new(0.0, 0.0, 0.0, 1.0);
  339. let mut position = None;
  340. for item in self.items {
  341. match item {
  342. BuilderItem::Text(text) => {
  343. let font_id = font_id.ok_or(Error::FontNotSet)?;
  344. let text = OwnedText::new(text)
  345. .with_extra(Extra { text_id: 0, color })
  346. .with_scale(scale)
  347. .with_font_id(font_id);
  348. match (sections.pop(), position.take()) {
  349. (Some(section), Some(pos)) => {
  350. sections.push(section);
  351. sections.push(
  352. OwnedSection::default()
  353. .with_screen_position(pos)
  354. .add_text(text),
  355. );
  356. }
  357. (Some(section), None) => {
  358. sections.push(section.add_text(text));
  359. }
  360. (None, Some(pos)) => sections.push(
  361. OwnedSection::<Extra>::default()
  362. .with_screen_position(pos)
  363. .add_text(text),
  364. ),
  365. (None, None) => {
  366. sections.push(OwnedSection::<Extra>::default().add_text(text))
  367. }
  368. };
  369. }
  370. BuilderItem::Position(x, y) => position = Some((x, y)),
  371. BuilderItem::Color(c) => color = c,
  372. BuilderItem::Scale(s) => scale = s,
  373. BuilderItem::Font(path) => font_id = Some(self.cache.font(&path)?),
  374. }
  375. }
  376. let text = Text::new(&self.cache, sections)?;
  377. let weak = Rc::downgrade(&text.inner);
  378. self.cache.add_text(weak)?;
  379. Ok(text)
  380. }
  381. pub fn position(mut self, x: f32, y: f32) -> Self {
  382. self.items.push(BuilderItem::Position(x, y));
  383. self
  384. }
  385. pub fn font<S>(mut self, path: S) -> Self
  386. where
  387. S: Display,
  388. {
  389. self.items.push(BuilderItem::Font(path.to_string()));
  390. self
  391. }
  392. pub fn color(self, r: f32, g: f32, b: f32, a: f32) -> Self {
  393. self.color_vec(Vector4f::new(r, g, b, a))
  394. }
  395. pub fn color_vec(mut self, color: Vector4f) -> Self {
  396. self.items.push(BuilderItem::Color(color));
  397. self
  398. }
  399. pub fn text<S>(mut self, text: S) -> Self
  400. where
  401. S: Display,
  402. {
  403. self.items.push(BuilderItem::Text(text.to_string()));
  404. self
  405. }
  406. pub fn scale(mut self, scale: f32) -> Self {
  407. self.items.push(BuilderItem::Scale(scale));
  408. self
  409. }
  410. }
  411. /* Text */
  412. pub struct Text {
  413. cache: TextCache,
  414. inner: Rc<RefCell<TextInner>>,
  415. }
  416. struct TextInner {
  417. array: VertexArray,
  418. program: Rc<Program>,
  419. texture: Rc<RefCell<Texture>>,
  420. sections: Vec<OwnedSection<Extra>>,
  421. vertex_count: usize,
  422. }
  423. #[derive(Default, Debug, Clone)]
  424. struct Extra {
  425. text_id: usize,
  426. color: Vector4f,
  427. }
  428. #[derive(Default, Clone)]
  429. struct Vertex {
  430. text_id: usize,
  431. data: VertexData,
  432. }
  433. #[repr(C, packed)]
  434. #[derive(Default, Debug, Clone)]
  435. struct VertexData {
  436. pos_min: Vector2f,
  437. pos_max: Vector2f,
  438. tex_min: Vector2f,
  439. tex_max: Vector2f,
  440. color: Vector4f,
  441. }
  442. impl Text {
  443. fn new(cache: &TextCache, sections: Vec<OwnedSection<Extra>>) -> Result<Self, Error> {
  444. const STRIDE: gl::GLsizei = size_of::<VertexData>() as _;
  445. const SIZE_VEC2: gl::GLsizei = size_of::<Vector2f>() as _;
  446. const OFFSET_POS_MIN: gl::GLsizei = 0;
  447. const OFFSET_POS_MAX: gl::GLsizei = OFFSET_POS_MIN + SIZE_VEC2;
  448. const OFFSET_TEX_MIN: gl::GLsizei = OFFSET_POS_MAX + SIZE_VEC2;
  449. const OFFSET_TEX_MAX: gl::GLsizei = OFFSET_TEX_MIN + SIZE_VEC2;
  450. const OFFSET_COLOR: gl::GLsizei = OFFSET_TEX_MAX + SIZE_VEC2;
  451. let buffer = ArrayBuffer::new(Target::ArrayBuffer)?;
  452. let array = VertexArray::builder()
  453. .bind_buffer(buffer)
  454. .vertex_attrib_pointer(0, 2, DataType::Float, false, STRIDE, OFFSET_POS_MIN)?
  455. .vertex_attrib_divisor(1)?
  456. .vertex_attrib_pointer(1, 2, DataType::Float, false, STRIDE, OFFSET_POS_MAX)?
  457. .vertex_attrib_divisor(1)?
  458. .vertex_attrib_pointer(2, 2, DataType::Float, false, STRIDE, OFFSET_TEX_MIN)?
  459. .vertex_attrib_divisor(1)?
  460. .vertex_attrib_pointer(3, 2, DataType::Float, false, STRIDE, OFFSET_TEX_MAX)?
  461. .vertex_attrib_divisor(1)?
  462. .vertex_attrib_pointer(4, 4, DataType::Float, false, STRIDE, OFFSET_COLOR)?
  463. .vertex_attrib_divisor(1)?
  464. .build()?;
  465. let cache = cache.clone();
  466. let program = cache.0.borrow().manager.0.borrow().program.clone();
  467. let texture = cache.0.borrow().texture.clone();
  468. let inner = TextInner {
  469. array,
  470. program,
  471. texture,
  472. sections,
  473. vertex_count: 0,
  474. };
  475. let text = Text {
  476. cache,
  477. inner: Rc::new(RefCell::new(inner)),
  478. };
  479. Ok(text)
  480. }
  481. pub fn render(&self, enable_blending: bool) {
  482. let inner = self.inner.borrow();
  483. let texture = inner.texture.borrow();
  484. if enable_blending {
  485. gl::enable(gl::BLEND);
  486. gl::blend_func(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA);
  487. }
  488. let _guard = BindGuard::new(&*texture);
  489. let _guard = BindGuard::new(&inner.array);
  490. let _guard = BindGuard::new(&*inner.program);
  491. gl::draw_arrays_instanced(gl::TRIANGLE_STRIP, 0, 4, inner.vertex_count as _);
  492. if enable_blending {
  493. gl::disable(gl::BLEND);
  494. }
  495. }
  496. pub fn update<S>(&mut self, mut index: usize, text: S) -> Result<(), Error>
  497. where
  498. S: Display,
  499. {
  500. let mut inner = self.inner.borrow_mut();
  501. for section in &mut inner.sections {
  502. if index < section.text.len() {
  503. section.text[index].text = text.to_string();
  504. break;
  505. } else {
  506. index -= section.text.len();
  507. }
  508. }
  509. drop(inner);
  510. self.cache.update()
  511. }
  512. }
  513. impl TextInner {
  514. fn update(&mut self, data: Vec<VertexData>) -> Result<(), Error> {
  515. let buffers = self.array.buffers_mut();
  516. buffers[0].buffer_data(Usage::StaticDraw, &data)?;
  517. self.vertex_count = data.len();
  518. Ok(())
  519. }
  520. }
  521. impl Hash for Extra {
  522. fn hash<H>(&self, state: &mut H)
  523. where
  524. H: Hasher,
  525. {
  526. self.text_id.hash(state);
  527. OrderedFloat::from(self.color[0]).hash(state);
  528. OrderedFloat::from(self.color[1]).hash(state);
  529. OrderedFloat::from(self.color[2]).hash(state);
  530. OrderedFloat::from(self.color[3]).hash(state);
  531. }
  532. }
  533. impl PartialEq for Extra {
  534. fn eq(&self, other: &Self) -> bool {
  535. self.text_id.eq(&other.text_id) && self.color.eq(&other.color)
  536. }
  537. }