3 #include <msp/fs/path.h>
4 #include <msp/gl/framebuffer.h>
5 #include <msp/gl/immediate.h>
6 #include <msp/gl/matrix.h>
7 #include <msp/gl/renderer.h>
8 #include <msp/gl/texture2d.h>
9 #include <msp/io/print.h>
12 #include "tracktype.h"
19 Overlay3D::Overlay3D(const GL::Font &f):
23 Overlay3D::~Overlay3D()
25 for(map<string, GL::Mesh *>::iterator i=graphics.begin(); i!=graphics.end(); ++i)
27 for(map<const Object3D *, Icon *>::iterator i=icons.begin(); i!=icons.end(); ++i)
31 void Overlay3D::set_label(const Object3D &track, const string &label)
33 get_icon(track).label = label;
34 update_icon(get_icon(track));
37 void Overlay3D::add_graphic(const Object3D &track, const string &grf_name)
39 const GL::Mesh *grf = get_graphic(grf_name);
43 Icon &icon = get_icon(track);
44 if(find(icon.graphics.begin(), icon.graphics.end(), grf)==icon.graphics.end())
45 icon.graphics.push_back(grf);
50 void Overlay3D::remove_graphic(const Object3D &track, const string &grf_name)
52 const GL::Mesh *grf = get_graphic(grf_name);
53 Icon &icon = get_icon(track);
54 icon.graphics.erase(remove(icon.graphics.begin(), icon.graphics.end(), grf), icon.graphics.end());
59 void Overlay3D::clear_graphics(const Object3D &track)
61 get_icon(track).graphics.clear();
62 update_icon(get_icon(track));
65 void Overlay3D::clear(const Object3D &track)
67 map<const Object3D *, Icon *>::iterator i = icons.find(&track);
75 void Overlay3D::render(GL::Renderer &renderer, const GL::Tag &) const
77 unsigned fb_width = GL::Framebuffer::current()->get_width();
78 unsigned fb_height = GL::Framebuffer::current()->get_height();
80 GL::Renderer::Push push(renderer);
81 GL::MatrixStack::Push push_proj(GL::MatrixStack::projection());
83 GL::MatrixStack::projection() = GL::Matrix::scaling(2.0/fb_width, 2.0/fb_height, 1.0);
87 int size = int(font.get_native_size()+0.5);
88 float spacing = round(size*1.1)/size;
89 float baseline = round((0.5-font.get_ascent()*0.5-font.get_descent()*0.5)*size)/size;
91 for(map<const Object3D *, Icon *>::const_iterator i=icons.begin(); i!=icons.end(); ++i)
93 if(!i->first->is_visible())
96 const Icon &icon = *i->second;
98 Vector node = i->first->get_node();
99 GL::Vector3 p = renderer.get_camera()->project(GL::Vector3(node.x, node.y, node.z));
100 p.x = int(p.x*0.5*fb_width-icon.width*size/2);
101 p.y = int(p.y*0.5*fb_height);
103 GL::Renderer::Push push2(renderer);
104 renderer.matrix_stack() = GL::Matrix::translation(p);
105 renderer.matrix_stack() *= GL::Matrix::scaling(size);
107 icon.background.draw(renderer);
109 glColor3f(0.0, 1.0, 0.0);
110 for(vector<const GL::Mesh *>::const_iterator j=icon.graphics.begin(); j!=icon.graphics.end(); ++j)
112 (*j)->draw(renderer);
113 renderer.matrix_stack() *= GL::Matrix::translation(spacing, 0, 0);
116 renderer.matrix_stack() *= GL::Matrix::translation(0, baseline, 0);
117 renderer.set_texture(&font.get_texture());
118 icon.text.draw(renderer);
121 glColor3f(1.0, 1.0, 1.0);
124 Overlay3D::Icon &Overlay3D::get_icon(const Object3D &track)
126 Icon *&icon = icons[&track];
133 const GL::Mesh *Overlay3D::get_graphic(const string &name)
135 GL::Mesh *&grf = graphics[name];
141 DataFile::load(*grf, (FS::Path("icons")/(name+".mesh")).str());
143 catch(const exception &e)
145 IO::print("Error loading overlay graphic '%s': %s\n", name, e.what());
154 void Overlay3D::update_icon(Icon &icon)
156 icon.background.clear();
158 icon.width = max(icon.graphics.size()*1.1+font.get_string_width(icon.label), 1.0);
161 GL::MeshBuilder bld(icon.background);
162 bld.color(0.2f, 0.2f, 0.2f, 0.7f);
164 bld.begin(GL::TRIANGLE_FAN);
165 bld.vertex(0.4, 0.5);
166 bld.vertex(icon.width-0.4, 0.5);
167 bld.vertex(icon.width-0.4, 1.2);
168 for(int i=4; i<=12; ++i)
169 bld.vertex(0.4+cos(i*M_PI/8)*0.7, 0.5+sin(i*M_PI/8)*0.7);
172 bld.begin(GL::TRIANGLE_FAN);
173 bld.vertex(icon.width-0.4, 0.5);
174 bld.vertex(0.4, 0.5);
175 bld.vertex(0.4, -0.2);
176 for(int i=-4; i<=4; ++i)
177 bld.vertex(icon.width-0.4+cos(i*M_PI/8)*0.7, 0.5+sin(i*M_PI/8)*0.7);
184 GL::MeshBuilder bld(icon.text);
185 bld.color(0.0f, 1.0f, 0.0f);
186 font.build_string(icon.label, bld);
191 Overlay3D::Icon::Icon():
193 background((GL::COLOR4_UBYTE, GL::VERTEX2)),
194 text((GL::COLOR4_UBYTE, GL::TEXCOORD2, GL::VERTEX2))