Text.cpp
Go to the documentation of this file.
1 #include "Text.hpp"
2 
4 
5 #warning "TODO - Text currently uses only MSDF variant of the text. Details about the problem and possible solutions are in comment below."
6 /*
7  The problem is that texture_id is set in first_pass but variants (and therefore texture_id) would be selected in second_pass.
8  One solution would be to have concept of unknown texture_ids in render queues, so that the sorting will be a bit problematic, but it would work.
9  Other solution is to have some kind of permanency of pointers in render queues - so that we would not need to add renderables
10  to render queues each frame (in first_pass) but only when their properties change (so that it can be done in second_pass which is not called each frame).
11  One problem with that would be the fact that we recompute draw order each frame in initialization part of first_pass - that is changed each frame,
12  so that needs to be set in first_pass - but maybe render queue could query that value during sorting phase of render."
13  Either way - lets test and profile and improve the element graph rendering before implementing this.
14 
15  -> Probably use the 'unknown' texture_id for now.
16  -> Or make renderer ask each instance for texture_id right before sorting, in render pass, after second pass.
17 */
18 
19 namespace iv
20 {
21 
22 Text::Text( Instance * inst ) :
23  Elem( inst ),
24  TextSegment( this ),
25  TranslucentElem( this ),
26  cm( inst, this, "Text", ClientMarker::Status() ),
27  attr_text( &this->cm, "" ),
28  attr_font( &this->cm, "" ),
29  attr_fontSize( &this->cm, 12 ),
30  attr_color( &this->cm, float4( 0.0f, 0.0f, 0.0f, 1.0f ) ),
31  mesh( inst ),
32  heap( inst, &this->cm )
33 {
34  this->cm.inherits( this->Elem::cm, this->TextSegment::cm, this->TranslucentElem::cm );
35  this->cm.owns( this->mesh.cm );
36 }
37 
39 {
40  static iv::TableId DebugTable = TableId::create( "Text" );
41  auto row = view->Table( DebugTable ).Row( this );
42 
43  row.Column( "text", this->attr_text.Get() );
44  row.Column( "font", this->attr_font.Get() );
45  row.Column( "font_size", this->attr_fontSize.Get() );
46  row.Column( "color", this->attr_color.Get() );
47 }
48 
50 {
51  this->heap.createClient< DVar_Field< ResourcePath > >( id )
52  ->Assign_Attribute_RW( &this->attr_font );
53 
54  return this;
55 }
56 
57 
58 Text * Text::enabled( bool val )
59 {
60  this->Elem::enabled( val );
61  return this;
62 }
63 
65 {
66  this->TranslucentElem::preblend( val );
67  return this;
68 }
69 
70 Text * Text::translucent( bool val )
71 {
72  this->TranslucentElem::translucent( val );
73  return this;
74 }
75 
76 Text * Text::text( std::string const & val )
77 {
78  this->attr_text.Set( val );
79  return this;
80 }
81 
82 Text * Text::font( ResourcePath const & val )
83 {
84  this->attr_font.Set( val );
85  return this;
86 }
87 
88 Text * Text::fontSize( float val )
89 {
90  this->attr_fontSize.Set( val );
91  return this;
92 }
93 
95 {
96  this->attr_color.Set( val );
97  return this;
98 }
99 /*
100 Text * Text::fixed_enabled_Set( bool val )
101 {
102  this->fixed_enabled.Set( val );
103  return this;
104 }
105 */
106 
108 {
109  if( this->attr_font.dirty() )
110  {
111  this->mesh.font_path( this->attr_font.Get() );
112  }
113 
114  if( this->attr_text.dirty() || this->attr_font.dirty() || this->attr_fontSize.dirty() )
115  {
116  er->QueueSecondPass( this );
117  this->geometry_dirty = true;
118  }
119 
120  // queue render
121  {
122  GLuint shader_id = this->mesh.program_id();
123  GLuint texture_id = this->mesh.texture_id();
124 
125  if( shader_id && texture_id )
126  {
127  if( this->attr_translucent.Get() )
128  er->AddRenderable_Translucent( this, shader_id, texture_id );
129  else
130  er->AddRenderable_Solid( this, shader_id, texture_id );
131  }
132  }
133 }
134 
135 FontMesh::Geometry Text::geometry_Compute( FontMesh::Location const & location )
136 {
137  return this->mesh.ComputeGeometry( this->attr_text.Get(), this->attr_fontSize.Get(), location );
138 }
139 
141 {
142  // refresh meshes
143  if( this->attr_text.clear_dirty() || this->attr_font.clear_dirty() || this->attr_fontSize.clear_dirty()
144  || this->location.clear_dirty() /*|| this->attr_fixedAllowed.clear_dirty()*/ )
145  {
146  //
147  er->Notify_SecondPass_Refresh( this );
148 
149  //
150  // TODO - maybe implement selection of font variant
151  this->mesh.GenerateMesh( this->attr_text.Get(), this->attr_fontSize.Get(), this->location.Get() );
152  }
153 
154  if( this->modelTransform.dirty() )
155  {
156  // clear
157  this->modelTransform.clear_dirty();
158 
159  //
160  // TODO - maybe implement selection of font variant - regenerate mesh if selected variant for given model_transform changed
161  }
162 }
163 
164 void Text::render( CameraState const & camera, std::optional< float > depth_override )
165 {
166  this->mesh.Render( camera, this->modelTransform.Get(), this->attr_color.Get(), this->attr_preblend.Get(), this->attr_translucent.Get(), depth_override, this->scissor.Get() );
167 }
168 
169 }