3 This file is part of the MSP Märklin suite
4 Copyright © 2010 Mikkosoft Productions, Mikko Rasa
5 Distributed under the GPL
10 #include <msp/fs/path.h>
11 #include <msp/gl/matrix.h>
12 #include <msp/gl/texture.h>
13 #include <msp/io/print.h>
16 #include "tracktype.h"
23 Overlay3D::Overlay3D(const Graphics::Window &w, const GL::Camera &c, const GL::Font &f):
29 Overlay3D::~Overlay3D()
31 for(map<string, GL::Mesh *>::iterator i=graphics.begin(); i!=graphics.end(); ++i)
33 for(map<const Track3D *, Icon *>::iterator i=icons.begin(); i!=icons.end(); ++i)
37 void Overlay3D::set_label(const Track3D &track, const string &label)
39 get_icon(track).label = label;
40 update_icon(get_icon(track));
43 void Overlay3D::add_graphic(const Track3D &track, const string &grf_name)
45 const GL::Mesh *grf = get_graphic(grf_name);
49 Icon &icon = get_icon(track);
50 if(find(icon.graphics.begin(), icon.graphics.end(), grf)==icon.graphics.end())
51 icon.graphics.push_back(grf);
56 void Overlay3D::remove_graphic(const Track3D &track, const string &grf_name)
58 const GL::Mesh *grf = get_graphic(grf_name);
59 Icon &icon = get_icon(track);
60 icon.graphics.erase(remove(icon.graphics.begin(), icon.graphics.end(), grf), icon.graphics.end());
65 void Overlay3D::clear_graphics(const Track3D &track)
67 get_icon(track).graphics.clear();
68 update_icon(get_icon(track));
71 void Overlay3D::clear(const Track3D &track)
73 map<const Track3D *, Icon *>::iterator i = icons.find(&track);
81 void Overlay3D::render(const GL::Tag &tag) const
85 GL::matrix_mode(GL::PROJECTION);
88 GL::scale(2.0/window.get_width(), 2.0/window.get_height(), 1.0);
89 GL::matrix_mode(GL::MODELVIEW);
95 int size = int(font.get_default_size()+0.5);
96 float spacing = round(size*1.1)/size;
97 float baseline = round((0.5-font.get_ascent()*0.5-font.get_descent()*0.5)*size)/size;
99 for(map<const Track3D *, Icon *>::const_iterator i=icons.begin(); i!=icons.end(); ++i)
101 const Icon &icon = *i->second;
103 const Point &pos = i->first->get_track().get_position();
106 i->first->get_type().get_bounds(0, minp, maxp);
107 float rot = i->first->get_track().get_rotation();
111 GL::Vector3 p((minp.x+maxp.x)/2, (minp.y+maxp.y)/2, 0);
112 p = GL::Vector3(pos.x+c*p.x-s*p.y, pos.y+s*p.x+c*p.y, pos.z+0.02);
113 p = camera.project(p);
115 GL::PushMatrix push_mat;
116 p.x = int(p.x*0.5*window.get_width()-icon.width*size/2);
117 p.y = int(p.y*0.5*window.get_height());
118 GL::translate(p.x, p.y, p.z);
119 GL::scale_uniform(size);
121 icon.background.draw();
123 glColor3f(0.0, 1.0, 0.0);
124 for(vector<const GL::Mesh *>::const_iterator j=icon.graphics.begin(); j!=icon.graphics.end(); ++j)
127 GL::translate(spacing, 0, 0);
130 GL::translate(0, baseline, 0);
131 font.draw_string(icon.label);
132 GL::Texture::unbind();
135 GL::matrix_mode(GL::PROJECTION);
137 GL::matrix_mode(GL::MODELVIEW);
142 Overlay3D::Icon &Overlay3D::get_icon(const Track3D &track)
144 Icon *&icon = icons[&track];
151 const GL::Mesh *Overlay3D::get_graphic(const string &name)
153 GL::Mesh *&grf = graphics[name];
159 DataFile::load(*grf, (FS::Path("icons")/(name+".mesh")).str());
161 catch(const Exception &e)
163 IO::print("Error loading overlay graphic '%s': %s\n", name, e.what());
172 void Overlay3D::update_icon(Icon &icon)
174 icon.background.clear();
176 icon.width = max(icon.graphics.size()*1.1+font.get_string_width(icon.label), 1.0);
178 GL::MeshBuilder bld(icon.background);
179 bld.color(0.2f, 0.2f, 0.2f, 0.7f);
181 bld.begin(GL::TRIANGLE_FAN);
182 bld.vertex(0.4, 0.5);
183 bld.vertex(icon.width-0.4, 0.5);
184 bld.vertex(icon.width-0.4, 1.2);
185 for(int i=4; i<=12; ++i)
186 bld.vertex(0.4+cos(i*M_PI/8)*0.7, 0.5+sin(i*M_PI/8)*0.7);
189 bld.begin(GL::TRIANGLE_FAN);
190 bld.vertex(icon.width-0.4, 0.5);
191 bld.vertex(0.4, 0.5);
192 bld.vertex(0.4, -0.2);
193 for(int i=-4; i<=4; ++i)
194 bld.vertex(icon.width-0.4+cos(i*M_PI/8)*0.7, 0.5+sin(i*M_PI/8)*0.7);
199 Overlay3D::Icon::Icon():
201 background((GL::COLOR4_UBYTE, GL::VERTEX2))
204 } // namespace Marklin