Ion
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
text.cc
Go to the documentation of this file.
1 
18 #include <memory>
19 #include <string>
20 
21 #include "ion/gfx/node.h"
22 #include "ion/gfx/renderer.h"
24 #include "ion/gfx/shape.h"
25 #include "ion/gfx/statetable.h"
26 #include "ion/gfx/uniform.h"
29 #include "ion/math/matrix.h"
30 #include "ion/math/range.h"
32 #include "ion/math/vector.h"
33 #include "ion/text/fontimage.h"
34 #include "ion/text/freetypefont.h"
35 #include "ion/text/layout.h"
37 
39 #include "GL/freeglut.h"
40 
41 namespace {
42 
44 
50 
51 
52 static unsigned char kFontData[] = {
53 #include "./fontdata.h"
54 };
55 
57 
62 
63 
64 struct GlobalState {
65  int window_width;
66  int window_height;
67  ion::gfx::NodePtr scene_root;
68  ion::gfx::RendererPtr renderer;
69 };
70 
71 static std::unique_ptr<GlobalState> s_global_state;
72 
74 
79 
80 
81 static const ion::text::FontPtr CreateFont() {
82  static const char kFontName[] = "ExampleFont";
83  static const size_t kFontSizeInPixels = 64U;
84  static const size_t kSdfPadding = 8U;
86  kFontName, kFontSizeInPixels, kSdfPadding, kFontData, sizeof(kFontData)));
87  return font;
88 }
89 
90 static const ion::gfx::NodePtr BuildTextNode(
91  const ion::text::FontImagePtr& font_image) {
93  options.target_size.Set(0.f, 2.f);
96  options.line_spacing = 1.5f;
97  const ion::text::Layout layout =
98  font_image->GetFont()->BuildLayout("Hello,\nWorld!", options);
99 
101  font_image, ion::gfxutils::ShaderManagerPtr(),
103  outline_builder->Build(layout, ion::gfx::BufferObject::kStreamDraw);
104  outline_builder->SetTextColor(ion::math::Vector4f(1.f, 1.f, .4f, 1.f));
105  outline_builder->SetOutlineColor(ion::math::Vector4f(.1f, .1f, .1f, 1.f));
106  outline_builder->SetHalfSmoothWidth(2.f);
107  outline_builder->SetOutlineWidth(6.f);
108  return outline_builder->GetNode();
109 }
110 
111 static const ion::gfx::NodePtr BuildScreenAlignedTextNode(
112  const ion::text::FontImagePtr& font_image) {
113  ion::text::LayoutOptions options;
114  options.target_point.Set(0.1f, 0.f);
115  options.target_size.Set(0.f, .06f);
118  const ion::text::Layout layout =
119  font_image->GetFont()->BuildLayout("Screen-Aligned text", options);
120 
122  font_image, ion::gfxutils::ShaderManagerPtr(),
124  outline_builder->Build(layout, ion::gfx::BufferObject::kStreamDraw);
125  outline_builder->SetTextColor(ion::math::Vector4f(1.f, .8f, .8f, 1.f));
126  outline_builder->SetOutlineColor(ion::math::Vector4f(.2f, .2f, .2f, 1.f));
127  outline_builder->SetHalfSmoothWidth(2.f);
128  outline_builder->SetOutlineWidth(6.f);
129  return outline_builder->GetNode();
130 }
131 
132 static const ion::gfx::NodePtr BuildGraph(int window_width, int window_height) {
134 
135  const ion::math::Vector2i window_size(window_width, window_height);
136 
137  ion::gfx::StateTablePtr state_table(
138  new ion::gfx::StateTable(window_width, window_height));
139  state_table->SetViewport(
140  ion::math::Range2i::BuildWithSize(ion::math::Point2i(0, 0), window_size));
141  state_table->SetClearColor(ion::math::Vector4f(0.3f, 0.3f, 0.5f, 1.0f));
142  state_table->SetClearDepthValue(1.f);
143  state_table->Enable(ion::gfx::StateTable::kDepthTest, true);
144  state_table->Enable(ion::gfx::StateTable::kCullFace, true);
145  root->SetStateTable(state_table);
146 
147  const ion::gfx::ShaderInputRegistryPtr& global_reg =
149 
150  root->AddUniform(global_reg->Create<ion::gfx::Uniform>(
151  "uViewportSize", window_size));
152 
153  ion::text::FontPtr font = CreateFont();
154  static const size_t kFontImageSize = 256U;
156  new ion::text::DynamicFontImage(font, kFontImageSize));
157 
158  ion::gfx::NodePtr text_node = BuildTextNode(font_image);
159  text_node->AddUniform(global_reg->Create<ion::gfx::Uniform>(
160  "uProjectionMatrix",
161  ion::math::PerspectiveMatrixFromView(ion::math::Anglef::FromDegrees(60.f),
162  1.f, .1f, 10.f)));
163  text_node->AddUniform(global_reg->Create<ion::gfx::Uniform>(
164  "uModelviewMatrix",
165  ion::math::LookAtMatrixFromCenter(ion::math::Point3f(2.f, 2.f, 4.f),
166  ion::math::Point3f::Zero(),
167  ion::math::Vector3f::AxisY())));
168  root->AddChild(text_node);
169 
170  ion::gfx::NodePtr aligned_text_node = BuildScreenAlignedTextNode(font_image);
171  aligned_text_node->AddUniform(global_reg->Create<ion::gfx::Uniform>(
172  "uProjectionMatrix",
173  ion::math::OrthographicMatrixFromFrustum(0.f, 1.f, 0.f, 1.f, -1.f, 1.f)));
174  aligned_text_node->AddUniform(global_reg->Create<ion::gfx::Uniform>(
175  "uModelviewMatrix", ion::math::Matrix4f::Identity()));
176  root->AddChild(aligned_text_node);
177 
178  return root;
179 }
180 
182 
187 
188 
189 static void Resize(int w, int h) {
190  s_global_state->window_width = w;
191  s_global_state->window_height = h;
192  glutPostRedisplay();
193 }
194 
195 static void Render() {
196  if (s_global_state.get())
197  s_global_state->renderer->DrawScene(s_global_state->scene_root);
198  glutSwapBuffers();
199 }
200 
201 static void Update() {
202  glutPostRedisplay();
203 }
204 
205 static void Keyboard(unsigned char key, int x, int y) {
206  glutPostRedisplay();
207 }
208 
209 static void KeyboardUp(unsigned char key, int x, int y) {
210  switch (key) {
211  case 27: // Escape.
212  s_global_state.reset(NULL);
213  glutLeaveMainLoop();
214  break;
215  }
216  glutPostRedisplay();
217 }
218 
219 } // anonymous namespace
220 
222 
227 
228 
229 int main(int argc, char* argv[]) {
230  glutInit(&argc, argv);
231 
232  s_global_state.reset(new GlobalState);
233  s_global_state->window_width = s_global_state->window_height = 800;
234  s_global_state->scene_root = BuildGraph(s_global_state->window_width,
235  s_global_state->window_height);
236 
237  glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE);
238  glutSetOption(GLUT_MULTISAMPLE, 16);
239  glutInitWindowSize(s_global_state->window_width,
240  s_global_state->window_height);
241 
242  glutCreateWindow("Ion rectangle example");
243  glutDisplayFunc(Render);
244  glutReshapeFunc(Resize);
245  glutKeyboardFunc(Keyboard);
246  glutKeyboardUpFunc(KeyboardUp);
247  glutIdleFunc(Update);
248 
251  s_global_state->renderer.Reset(new ion::gfx::Renderer(graphics_manager));
252 
253  glutMainLoop();
254 }
GraphicsManager manages the graphics library for an application.
This derived Font class represents a FreeType2 font.
Definition: freetypefont.h:35
static const ShaderInputRegistryPtr & GetGlobalRegistry()
Returns the ShaderInputRegistry instance representing all supported global uniforms and attributes...
math::Point2f target_point
Location of the text rectangle. (Default: origin)
Definition: layout.h:110
A Uniform instance represents a uniform shader argument.
Definition: uniform.h:76
This struct defines parameters affecting layout of a single text string when passed to BuildLayout()...
Definition: layout.h:101
ION_API const Matrix< 4, T > LookAtMatrixFromCenter(const Point< 3, T > &eye, const Point< 3, T > &center, const Vector< 3, T > &up)
View matrices.
static Matrix Identity()
Returns an identity Matrix.
Definition: matrix.h:276
ION_API const Matrix< 4, T > PerspectiveMatrixFromView(const Angle< T > &fovy, T aspect, T z_near, T z_far)
Returns a 4x4 perspective projection matrix based on the given parameters, which follow the conventio...
math::Vector2f target_size
Target width and height of the text rectangle. (Default: 0 in x, 1 in y)
Definition: layout.h:112
A Layout instance specifies how glyphs are arranged to form text.
Definition: layout.h:127
int main(int argc, char *argv[])
Mainline.
Definition: text.cc:229
OutlineBuilder is a derived Builder class that can render text with outlines.
HorizontalAlignment horizontal_alignment
Text alignment in the horizontal direction. (Default: kAlignLeft)
Definition: layout.h:114
ION_API const Matrix< 4, T > OrthographicMatrixFromFrustum(T x_left, T x_right, T y_bottom, T y_top, T z_near, T z_far)
Projection matrices.
VerticalAlignment vertical_alignment
Text alignment in the vertical direction. (Default: kAlignBaseline)
Definition: layout.h:116
float line_spacing
Spacing between baselines of lines of multi-line text, expressed as a fraction of the font's FontMetr...
Definition: layout.h:119
A StateTable represents a collection of graphical state items that affect OpenGL rendering.
Definition: statetable.h:48
A Node instance represents a node in a scene graph.
Definition: node.h:45
A SharedPtr is a smart shared pointer to an instance of some class that implements reference counting...
Definition: sharedptr.h:60
The Renderer class handles rendering ION scene graphs using OpenGL.
Definition: renderer.h:50
DynamicFontImage is a derived FontImage that may contain any number of ImageData instances.
Definition: fontimage.h:208