]> git.tdb.fi Git - r2c2.git/blobdiff - source/3d/overlay.cpp
Make some internal colors darker to match linear color space
[r2c2.git] / source / 3d / overlay.cpp
index bc206f987ac6c930275edbce4c9700e29dc1896d..2a26915a6e5fce5288254ac8b9d3af907bac7f5b 100644 (file)
@@ -1,15 +1,11 @@
-/* $Id$
-
-This file is part of the MSP Märklin suite
-Copyright © 2010 Mikkosoft Productions, Mikko Rasa
-Distributed under the GPL
-*/
-
 #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"
@@ -18,11 +14,9 @@ Distributed under the GPL
 using namespace std;
 using namespace Msp;
 
-namespace Marklin {
+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)
 { }
 
@@ -30,17 +24,17 @@ Overlay3D::~Overlay3D()
 {
        for(map<string, GL::Mesh *>::iterator i=graphics.begin(); i!=graphics.end(); ++i)
                delete i->second;
-       for(map<const Track3D *, Icon *>::iterator i=icons.begin(); i!=icons.end(); ++i)
+       for(map<const Object3D *, Icon *>::iterator i=icons.begin(); i!=icons.end(); ++i)
                delete i->second;
 }
 
-void Overlay3D::set_label(const Track3D &track, const string &label)
+void Overlay3D::set_label(const Object3D &track, const string &label)
 {
        get_icon(track).label = label;
        update_icon(get_icon(track));
 }
 
-void Overlay3D::add_graphic(const Track3D &track, const string &grf_name)
+void Overlay3D::add_graphic(const Object3D &track, const string &grf_name)
 {
        const GL::Mesh *grf = get_graphic(grf_name);
        if(!grf)
@@ -53,7 +47,7 @@ void Overlay3D::add_graphic(const Track3D &track, const string &grf_name)
        update_icon(icon);
 }
 
-void Overlay3D::remove_graphic(const Track3D &track, const string &grf_name)
+void Overlay3D::remove_graphic(const Object3D &track, const string &grf_name)
 {
        const GL::Mesh *grf = get_graphic(grf_name);
        Icon &icon = get_icon(track);
@@ -62,15 +56,15 @@ void Overlay3D::remove_graphic(const Track3D &track, const string &grf_name)
        update_icon(icon);
 }
 
-void Overlay3D::clear_graphics(const Track3D &track)
+void Overlay3D::clear_graphics(const Object3D &track)
 {
        get_icon(track).graphics.clear();
        update_icon(get_icon(track));
 }
 
-void Overlay3D::clear(const Track3D &track)
+void Overlay3D::clear(const Object3D &track)
 {
-       map<const Track3D *, Icon *>::iterator i = icons.find(&track);
+       map<const Object3D *, Icon *>::iterator i = icons.find(&track);
        if(i!=icons.end())
        {
                delete i->second;
@@ -78,68 +72,55 @@ void Overlay3D::clear(const Track3D &track)
        }
 }
 
-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_native_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);
+               GL::Vector3 p = renderer.get_camera()->project(i->first->get_node());
+               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 Track3D *, 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)
                {
-                       const Icon &icon = *i->second;
-
-                       const Point &pos = i->first->get_track().get_position();
-                       Point minp;
-                       Point maxp;
-                       i->first->get_type().get_bounds(0, minp, maxp);
-                       float rot = i->first->get_track().get_rotation();
-                       float c = cos(rot);
-                       float s = sin(rot);
-
-                       GL::Vector3 p((minp.x+maxp.x)/2, (minp.y+maxp.y)/2, 0);
-                       p = GL::Vector3(pos.x+c*p.x-s*p.y, pos.y+s*p.x+c*p.y, pos.z+0.02);
-                       p = camera.project(p);
-
-                       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);
-                       font.draw_string(icon.label);
-                       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();
+               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 Track3D &track)
+Overlay3D::Icon &Overlay3D::get_icon(const Object3D &track)
 {
        Icon *&icon = icons[&track];
        if(!icon)
@@ -158,7 +139,7 @@ const GL::Mesh *Overlay3D::get_graphic(const string &name)
                {
                        DataFile::load(*grf, (FS::Path("icons")/(name+".mesh")).str());
                }
-               catch(const Exception &e)
+               catch(const exception &e)
                {
                        IO::print("Error loading overlay graphic '%s': %s\n", name, e.what());
                        delete grf;
@@ -175,30 +156,41 @@ void Overlay3D::update_icon(Icon &icon)
 
        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.05f, 0.05f, 0.05f, 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.build_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 Marklin
+} // namespace R2C2