#include <algorithm>
#include <cmath>
#include <msp/fs/path.h>
+#include <msp/gl/framebuffer.h>
#include <msp/gl/immediate.h>
#include <msp/gl/matrix.h>
-#include <msp/gl/texture.h>
+#include <msp/gl/renderer.h>
+#include <msp/gl/texture2d.h>
#include <msp/io/print.h>
#include "overlay.h"
#include "track.h"
namespace R2C2 {
-Overlay3D::Overlay3D(const Graphics::Window &w, const GL::Camera &c, const GL::Font &f):
- window(w),
- camera(c),
+Overlay3D::Overlay3D(const GL::Font &f):
font(f)
{ }
}
}
-void Overlay3D::render(const GL::Tag &tag) const
+void Overlay3D::render(GL::Renderer &renderer, const GL::Tag &) const
{
- if(tag==0)
+ unsigned fb_width = GL::Framebuffer::current()->get_width();
+ unsigned fb_height = GL::Framebuffer::current()->get_height();
+
+ GL::Renderer::Push push(renderer);
+ GL::MatrixStack::Push push_proj(GL::MatrixStack::projection());
+
+ GL::MatrixStack::projection() = GL::Matrix::scaling(2.0/fb_width, 2.0/fb_height, 1.0);
+
+ glLineWidth(1);
+
+ int size = int(font.get_default_size()+0.5);
+ float spacing = round(size*1.1)/size;
+ float baseline = round((0.5-font.get_ascent()*0.5-font.get_descent()*0.5)*size)/size;
+
+ for(map<const Object3D *, Icon *>::const_iterator i=icons.begin(); i!=icons.end(); ++i)
{
- GL::matrix_mode(GL::PROJECTION);
- GL::push_matrix();
- GL::load_identity();
- GL::scale(2.0/window.get_width(), 2.0/window.get_height(), 1.0);
- GL::matrix_mode(GL::MODELVIEW);
- GL::push_matrix();
- GL::load_identity();
+ if(!i->first->is_visible())
+ continue;
+
+ const Icon &icon = *i->second;
- glLineWidth(1);
+ Vector node = i->first->get_node();
+ GL::Vector3 p = renderer.get_camera()->project(GL::Vector3(node.x, node.y, node.z));
+ p.x = int(p.x*0.5*fb_width-icon.width*size/2);
+ p.y = int(p.y*0.5*fb_height);
- int size = int(font.get_default_size()+0.5);
- float spacing = round(size*1.1)/size;
- float baseline = round((0.5-font.get_ascent()*0.5-font.get_descent()*0.5)*size)/size;
+ GL::Renderer::Push push2(renderer);
+ renderer.matrix_stack() = GL::Matrix::translation(p);
+ renderer.matrix_stack() *= GL::Matrix::scaling(size);
- for(map<const Object3D *, Icon *>::const_iterator i=icons.begin(); i!=icons.end(); ++i)
+ icon.background.draw(renderer);
+
+ glColor3f(0.0, 1.0, 0.0);
+ for(vector<const GL::Mesh *>::const_iterator j=icon.graphics.begin(); j!=icon.graphics.end(); ++j)
{
- if(!i->first->is_visible())
- continue;
-
- const Icon &icon = *i->second;
-
- Vector node = i->first->get_node();
- GL::Vector3 p = camera.project(GL::Vector3(node.x, node.y, node.z));
-
- GL::PushMatrix push_mat;
- p.x = int(p.x*0.5*window.get_width()-icon.width*size/2);
- p.y = int(p.y*0.5*window.get_height());
- GL::translate(p.x, p.y, p.z);
- GL::scale_uniform(size);
-
- icon.background.draw();
-
- glColor3f(0.0, 1.0, 0.0);
- for(vector<const GL::Mesh *>::const_iterator j=icon.graphics.begin(); j!=icon.graphics.end(); ++j)
- {
- (*j)->draw();
- GL::translate(spacing, 0, 0);
- }
-
- GL::translate(0, baseline, 0);
- GL::Immediate imm((GL::TEXCOORD2, GL::COLOR4_UBYTE, GL::VERTEX2));
- imm.color(0.0f, 1.0f, 0.0f);
- font.draw_string(icon.label, imm);
- GL::Texture::unbind();
+ (*j)->draw(renderer);
+ renderer.matrix_stack() *= GL::Matrix::translation(spacing, 0, 0);
}
- GL::matrix_mode(GL::PROJECTION);
- GL::pop_matrix();
- GL::matrix_mode(GL::MODELVIEW);
- GL::pop_matrix();
-
- glColor3f(1.0, 1.0, 1.0);
+ renderer.matrix_stack() *= GL::Matrix::translation(0, baseline, 0);
+ renderer.set_texture(&font.get_texture());
+ icon.text.draw(renderer);
}
+
+ glColor3f(1.0, 1.0, 1.0);
}
Overlay3D::Icon &Overlay3D::get_icon(const Object3D &track)
icon.width = max(icon.graphics.size()*1.1+font.get_string_width(icon.label), 1.0);
- GL::MeshBuilder bld(icon.background);
- bld.color(0.2f, 0.2f, 0.2f, 0.7f);
-
- bld.begin(GL::TRIANGLE_FAN);
- bld.vertex(0.4, 0.5);
- bld.vertex(icon.width-0.4, 0.5);
- bld.vertex(icon.width-0.4, 1.2);
- for(int i=4; i<=12; ++i)
- bld.vertex(0.4+cos(i*M_PI/8)*0.7, 0.5+sin(i*M_PI/8)*0.7);
- bld.end();
-
- bld.begin(GL::TRIANGLE_FAN);
- bld.vertex(icon.width-0.4, 0.5);
- bld.vertex(0.4, 0.5);
- bld.vertex(0.4, -0.2);
- for(int i=-4; i<=4; ++i)
- bld.vertex(icon.width-0.4+cos(i*M_PI/8)*0.7, 0.5+sin(i*M_PI/8)*0.7);
- bld.end();
+ {
+ GL::MeshBuilder bld(icon.background);
+ bld.color(0.2f, 0.2f, 0.2f, 0.7f);
+
+ bld.begin(GL::TRIANGLE_FAN);
+ bld.vertex(0.4, 0.5);
+ bld.vertex(icon.width-0.4, 0.5);
+ bld.vertex(icon.width-0.4, 1.2);
+ for(int i=4; i<=12; ++i)
+ bld.vertex(0.4+cos(i*M_PI/8)*0.7, 0.5+sin(i*M_PI/8)*0.7);
+ bld.end();
+
+ bld.begin(GL::TRIANGLE_FAN);
+ bld.vertex(icon.width-0.4, 0.5);
+ bld.vertex(0.4, 0.5);
+ bld.vertex(0.4, -0.2);
+ for(int i=-4; i<=4; ++i)
+ bld.vertex(icon.width-0.4+cos(i*M_PI/8)*0.7, 0.5+sin(i*M_PI/8)*0.7);
+ bld.end();
+ }
+
+ icon.text.clear();
+
+ {
+ GL::MeshBuilder bld(icon.text);
+ bld.color(0.0f, 1.0f, 0.0f);
+ font.draw_string(icon.label, bld);
+ }
}
Overlay3D::Icon::Icon():
width(1.0),
- background((GL::COLOR4_UBYTE, GL::VERTEX2))
+ background((GL::COLOR4_UBYTE, GL::VERTEX2)),
+ text((GL::COLOR4_UBYTE, GL::TEXCOORD2, GL::VERTEX2))
{ }
} // namespace R2C2