]> git.tdb.fi Git - libs/gl.git/blob - source/render/text.cpp
Make VertexFormat capable of storing type information
[libs/gl.git] / source / render / text.cpp
1 #include "meshbuilder.h"
2 #include "program.h"
3 #include "renderer.h"
4 #include "text.h"
5 #include "texture2d.h"
6
7 using namespace std;
8
9 namespace Msp {
10 namespace GL {
11
12 Text::Text(const Font &f, const Technique *tech, Tag tex_slot):
13         ObjectInstance(object),
14         font(f),
15         mesh((TEXCOORD2, VERTEX2)),
16         horz_align(0.0f),
17         vert_offset(0.0f),
18         width(0.0f)
19 {
20         object.set_mesh(&mesh);
21         if(tech)
22                 set_technique(tech, tex_slot);
23 }
24
25 void Text::set_technique(const Technique *tech, Tag tex_slot)
26 {
27         if(tech)
28         {
29                 if(!tex_slot.id && tech->has_pass(Tag()))
30                         if(const Program *shprog = tech->get_pass(Tag()).get_shader_program())
31                         {
32                                 if(shprog->get_uniform_location(Tag("font_tex"))>=0)
33                                         tex_slot = "font_tex";
34                                 else if(shprog->get_uniform_location(Tag("color_tex"))>=0)
35                                         tex_slot = "color_tex";
36                                 else if(shprog->get_uniform_location(Tag("diffuse_map"))>=0)
37                                         tex_slot = "diffuse_map";
38                                 else if(shprog->get_uniform_location(Tag("base_color_map"))>=0)
39                                         tex_slot = "base_color_map";
40                         }
41
42                 object.set_technique(tech);
43                 texture_slot = tex_slot;
44         }
45         else
46         {
47                 object.set_technique(0);
48                 texture_slot = Tag();
49         }
50 }
51
52 void Text::set_text(const string &text, StringCodec::Decoder &dec)
53 {
54         clear();
55         width = font.get_string_width(text, dec);
56         MeshBuilder bld(mesh);
57         bld.transform(Matrix::translation(Vector3(-horz_align*width, vert_offset, 0.0f)));
58         font.build_string(text, dec, bld);
59 }
60
61 void Text::clear()
62 {
63         mesh.clear();
64         width = 0;
65 }
66
67 void Text::set_alignment(HorizontalAlign ha, VerticalAlign va)
68 {
69         float h;
70         switch(ha)
71         {
72         case LEFT: h = 0.0f; break;
73         case CENTER: h = 0.5f; break;
74         case RIGHT: h = 1.0f; break;
75         default: throw invalid_argument("Text::set_alignment");
76         }
77
78         float v;
79         switch(va)
80         {
81         case DESCENT: v = -font.get_descent(); break;
82         case BASELINE: v = 0.0f; break;
83         case MIDLINE: v = font.get_cap_height()/2; break;
84         case ASCENT: v = font.get_ascent(); break;
85         default: throw invalid_argument("Text::set_alignment");
86         }
87
88         set_alignment(h, v);
89 }
90
91 void Text::set_alignment(float h, float v)
92 {
93         if(h==horz_align && -v==vert_offset)
94                 return;
95
96         float horz_adjust = (horz_align-h)*width;
97         float vert_adjust = -v-vert_offset;
98         horz_align = h;
99         vert_offset = -v;
100
101         unsigned pos_offset = mesh.get_vertices().get_format().offset(VERTEX2);
102         unsigned n_vertices = mesh.get_n_vertices();
103         for(unsigned i=0; i<n_vertices; ++i)
104         {
105                 float *pos = reinterpret_cast<float *>(mesh.modify_vertex(i)+pos_offset);
106                 pos[0] += horz_adjust;
107                 pos[1] += vert_adjust;
108         }
109 }
110
111 void Text::setup_render(Renderer &renderer, Tag tag) const
112 {
113         ObjectInstance::setup_render(renderer, tag);
114         renderer.set_texture(texture_slot, &font.get_texture());
115 }
116
117 } // namespace GL
118 } // namespace Msp