From: Mikko Rasa Date: Sun, 21 Feb 2010 20:01:37 +0000 (+0000) Subject: Use GL::Renderables and a Pipeline for rendering X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=47341c72a70e6cf9d8e963705a50197bbc20a87d;p=r2c2.git Use GL::Renderables and a Pipeline for rendering Add lighting to designer --- diff --git a/source/3d/catalogue.cpp b/source/3d/catalogue.cpp index 994d5f4..50f0484 100644 --- a/source/3d/catalogue.cpp +++ b/source/3d/catalogue.cpp @@ -5,6 +5,7 @@ Copyright © 2010 Mikkosoft Productions, Mikko Rasa Distributed under the GPL */ +#include #include "catalogue.h" #include "tracktype.h" @@ -14,11 +15,17 @@ using namespace Msp; namespace Marklin { Catalogue3D::Catalogue3D(const Catalogue &c): - catalogue(c) + catalogue(c), + endpoint_mesh((GL::NORMAL3, GL::VERTEX3)) { const map &trks = catalogue.get_tracks(); for(map::const_iterator i=trks.begin(); i!=trks.end(); ++i) tracks[i->second] = new TrackType3D(*this, *i->second); + + ballast_material.set_diffuse(GL::Color(0.25, 0.25, 0.25)); + rail_material.set_diffuse(GL::Color(0.85, 0.85, 0.85)); + + build_endpoint_mesh(); } const TrackType3D &Catalogue3D::get_track(const TrackType &tt) const @@ -30,4 +37,29 @@ const TrackType3D &Catalogue3D::get_track(const TrackType &tt) const return *i->second; } +void Catalogue3D::build_endpoint_mesh() +{ + const Profile &ballast_profile = catalogue.get_ballast_profile(); + const Point &ballast_min = ballast_profile.get_min_coords(); + const Point &ballast_max = ballast_profile.get_max_coords(); + + const Profile &rail_profile = catalogue.get_rail_profile(); + const Point &rail_min = rail_profile.get_min_coords(); + const Point &rail_max = rail_profile.get_max_coords(); + + float gauge = catalogue.get_gauge(); + + float width = max(max(-ballast_min.x, ballast_max.x)*2, gauge+(rail_max.x-rail_min.x)*2)+0.004; + float height = ballast_max.y-ballast_min.y+rail_max.y-rail_min.y+0.01; + + GL::MeshBuilder bld(endpoint_mesh); + bld.normal(1, 0, 0); + bld.begin(GL::QUADS); + bld.vertex(0, width/2, 0); + bld.vertex(0, width/2, height); + bld.vertex(0, -width/2, height); + bld.vertex(0, -width/2, 0); + bld.end(); +} + } // namespace Marklin diff --git a/source/3d/catalogue.h b/source/3d/catalogue.h index 689756d..b27683c 100644 --- a/source/3d/catalogue.h +++ b/source/3d/catalogue.h @@ -9,6 +9,7 @@ Distributed under the GPL #define MARKLIN3D_CATALOGUE_H_ #include +#include #include "libmarklin/catalogue.h" namespace Marklin { @@ -20,13 +21,20 @@ class Catalogue3D private: const Catalogue &catalogue; std::map tracks; - Msp::GL::Material *ballast_material; + Msp::GL::Material ballast_material; + Msp::GL::Material rail_material; + Msp::GL::Mesh endpoint_mesh; public: Catalogue3D(const Catalogue &); const Catalogue &get_catalogue() const { return catalogue; } const TrackType3D &get_track(const TrackType &) const; + const Msp::GL::Material &get_ballast_material() const { return ballast_material; } + const Msp::GL::Material &get_rail_material() const { return rail_material; } + const Msp::GL::Mesh &get_endpoint_mesh() const { return endpoint_mesh; } +private: + void build_endpoint_mesh(); }; } diff --git a/source/3d/endpoint.cpp b/source/3d/endpoint.cpp new file mode 100644 index 0000000..c11f45f --- /dev/null +++ b/source/3d/endpoint.cpp @@ -0,0 +1,53 @@ +/* $Id$ + +This file is part of the MSP Märklin suite +Copyright © 2010 Mikkosoft Productions, Mikko Rasa +Distributed under the GPL +*/ + +#include +#include +#include +#include "endpoint.h" +#include "layout.h" +#include "track.h" + +using namespace Msp; + +namespace Marklin { + +Endpoint3D::Endpoint3D(const Track3D &t, unsigned i): + track(t), + index(i), + mesh(track.get_layout().get_catalogue().get_endpoint_mesh()) +{ + track.get_layout().get_endpoint_scene().add(*this); +} + +Endpoint3D::~Endpoint3D() +{ + track.get_layout().get_endpoint_scene().remove(*this); +} + +void Endpoint3D::render(const GL::Tag &tag) const +{ + if(tag==0) + { + Point p = track.get_track().get_endpoint_position(index); + float a = track.get_track().get_endpoint_direction(index)+M_PI; + + GL::PushMatrix push_mat; + GL::translate(p.x, p.y, p.z); + GL::rotate(a*180/M_PI, 0, 0, 1); + + GL::set(GL_CULL_FACE, track.get_track().get_link(index)); + if(track.get_track().get_link(index)) + glColor4f(0.5, 0, 1, 0.5); + else + glColor4f(1, 0, 0.5, 0.5); + + mesh.draw(); + } +} + +} // namespace Marklin diff --git a/source/3d/endpoint.h b/source/3d/endpoint.h new file mode 100644 index 0000000..0abc526 --- /dev/null +++ b/source/3d/endpoint.h @@ -0,0 +1,35 @@ +/* $Id$ + +This file is part of the MSP Märklin suite +Copyright © 2010 Mikkosoft Productions, Mikko Rasa +Distributed under the GPL +*/ + +#ifndef MARKLIN3D_ENDPOINT_H_ +#define MARKLIN3D_ENDPOINT_H_ + +#include +#include +#include "libmarklin/track.h" + +namespace Marklin { + +class Track3D; + +class Endpoint3D: public Msp::GL::Renderable +{ +private: + const Track3D &track; + unsigned index; + const Msp::GL::Mesh &mesh; + +public: + Endpoint3D(const Track3D &, unsigned); + ~Endpoint3D(); + + virtual void render(const Msp::GL::Tag &) const; +}; + +} // namespace Marklin + +#endif diff --git a/source/3d/layout.cpp b/source/3d/layout.cpp index 633baa1..1b54e4b 100644 --- a/source/3d/layout.cpp +++ b/source/3d/layout.cpp @@ -29,8 +29,8 @@ Layout3D::Layout3D(Layout &l): Layout3D::~Layout3D() { - for(list::iterator i=tracks.begin(); i!=tracks.end(); ++i) - delete *i; + while(!tracks.empty()) + delete tracks.front(); } void Layout3D::set_quality(unsigned q) @@ -38,21 +38,16 @@ void Layout3D::set_quality(unsigned q) quality = q; } -void Layout3D::render(bool endpoints) const +void Layout3D::add_track(Track3D &t) { - GL::Texture::unbind(); - glEnable(GL_DEPTH_TEST); + tracks.push_back(&t); +} - for(list::const_iterator i=tracks.begin(); i!=tracks.end(); ++i) - (*i)->render(); - - if(endpoints) - { - glDepthMask(false); - for(list::const_iterator i=tracks.begin(); i!=tracks.end(); ++i) - (*i)->render_endpoints(); - glDepthMask(true); - } +void Layout3D::remove_track(Track3D &t) +{ + list::iterator i = find(tracks.begin(), tracks.end(), &t); + if(i!=tracks.end()) + tracks.erase(i); } Track3D &Layout3D::get_track(const Track &t) const @@ -60,7 +55,7 @@ Track3D &Layout3D::get_track(const Track &t) const for(list::const_iterator i=tracks.begin(); i!=tracks.end(); ++i) if(&(*i)->get_track()==&t) return **i; - + throw KeyError("Unknown track"); } @@ -99,7 +94,7 @@ Track3D *Layout3D::pick_track(float x, float y, float size) const glPopMatrix(); - render(); + scene.render(0); glDisable(GL_CLIP_PLANE0); glDisable(GL_CLIP_PLANE1); @@ -121,7 +116,7 @@ Track3D *Layout3D::pick_track(float x, float y, float size) const void Layout3D::track_added(Track &t) { - tracks.push_back(new Track3D(*this, t)); + new Track3D(*this, t); } void Layout3D::track_removed(Track &t) @@ -130,7 +125,6 @@ void Layout3D::track_removed(Track &t) if(&(*i)->get_track()==&t) { delete *i; - tracks.erase(i); return; } } diff --git a/source/3d/layout.h b/source/3d/layout.h index 21686de..a7fbdb9 100644 --- a/source/3d/layout.h +++ b/source/3d/layout.h @@ -8,6 +8,7 @@ Distributed under the GPL #ifndef MARKLIN3D_LAYOUT_H_ #define MARKLIN3D_LAYOUT_H_ +#include #include "libmarklin/layout.h" #include "catalogue.h" #include "track.h" @@ -20,6 +21,8 @@ private: Layout &layout; Catalogue3D catalogue; std::list tracks; + Msp::GL::Scene scene; + Msp::GL::Scene ep_scene; unsigned quality; public: @@ -28,10 +31,16 @@ public: const Catalogue3D &get_catalogue() const { return catalogue; } void set_quality(unsigned); + + void add_track(Track3D &); + void remove_track(Track3D &); const std::list &get_tracks() const { return tracks; } - void render(bool =false) const; Track3D &get_track(const Track &) const; Track3D *pick_track(float, float, float) const; + + Msp::GL::Scene &get_scene() { return scene; } + Msp::GL::Scene &get_endpoint_scene() { return ep_scene; } + private: void track_added(Track &); void track_removed(Track &); diff --git a/source/3d/track.cpp b/source/3d/track.cpp index c3eb388..3285796 100644 --- a/source/3d/track.cpp +++ b/source/3d/track.cpp @@ -6,9 +6,10 @@ Distributed under the GPL */ #include -#include +#include #include #include "libmarklin/tracktype.h" +#include "endpoint.h" #include "layout.h" #include "track.h" #include "tracktype.h" @@ -23,7 +24,23 @@ Track3D::Track3D(Layout3D &l, Track &t): track(t), type(layout.get_catalogue().get_track(track.get_type())), color(1, 1, 1) -{ } +{ + layout.add_track(*this); + layout.get_scene().add(*this); + + const vector &type_eps = track.get_type().get_endpoints(); + for(unsigned i=0; i::iterator i=endpoints.begin(); i!=endpoints.end(); ++i) + delete *i; +} void Track3D::set_color(const Msp::GL::Color &c) { @@ -42,6 +59,8 @@ void Track3D::get_bounds(float angle, Point &minp, Point &maxp) const maxp.x += c*pos.x-s*pos.y; minp.y += s*pos.x+c*pos.y; maxp.y += s*pos.x+c*pos.y; + minp.z += pos.z; + maxp.z += pos.z; float slope = track.get_slope(); if(slope>0) @@ -50,96 +69,22 @@ void Track3D::get_bounds(float angle, Point &minp, Point &maxp) const minp.z += slope; } -void Track3D::render() const -{ - prepare_render(true); - - glPushName(reinterpret_cast(this)); - - type.render(); - - glPopName(); - glPopMatrix(); -} - -void Track3D::render_endpoints() const -{ - prepare_render(false); - - const vector &endpoints = track.get_type().get_endpoints(); - for(unsigned i=0; i1e-4) - { - Point p; - if(track.get_slope()>0) - { - p = endpoints[1].pos; - p.z += track.get_slope(); - } - else - p = endpoints[0].pos; - glBegin(GL_TRIANGLE_STRIP); - for(unsigned i=0; i<=16; ++i) - { - float c = cos(i*M_PI/8); - float s = sin(i*M_PI/8); - glNormal3f(c, s, 0); - glVertex3f(p.x+c*0.01, p.y+s*0.01, p.z); - glVertex3f(p.x+c*0.01, p.y+s*0.01, -track.get_position().z); - } - glEnd(); - } - - glPopMatrix(); -} - -void Track3D::render_path(int path) const +void Track3D::render(const GL::Tag &tag) const { - prepare_render(true); - - (void)path; - /*varray.apply(); - if(path>=0 && static_cast(path)(this)); + + type.render(tag); + + glPopName(); } } // namespace Marklin diff --git a/source/3d/track.h b/source/3d/track.h index fe24b9a..cf994dd 100644 --- a/source/3d/track.h +++ b/source/3d/track.h @@ -10,6 +10,7 @@ Distributed under the GPL #include #include +#include #include #include #include "libmarklin/track.h" @@ -17,28 +18,29 @@ Distributed under the GPL namespace Marklin { +class Endpoint3D; class Layout3D; class TrackType3D; -class Track3D +class Track3D: public Msp::GL::Renderable { private: Layout3D &layout; Track &track; const TrackType3D &type; + std::vector endpoints; Msp::GL::Color color; public: Track3D(Layout3D &, Track &); + ~Track3D(); + Layout3D &get_layout() const { return layout; } Track &get_track() const { return track; } void set_color(const Msp::GL::Color &); void get_bounds(float, Point &, Point &) const; - void render() const; - void render_endpoints() const; - void render_path(int) const; -private: - void prepare_render(bool) const; + + virtual void render(const Msp::GL::Tag &) const; }; } // namespace Marklin diff --git a/source/3d/tracktype.cpp b/source/3d/tracktype.cpp index 26be527..94a941a 100644 --- a/source/3d/tracktype.cpp +++ b/source/3d/tracktype.cpp @@ -72,6 +72,7 @@ Iter graham_scan(Iter begin, Iter end) namespace Marklin { TrackType3D::TrackType3D(const Catalogue3D &cat3d, const TrackType &tt): + catalogue(cat3d), ballast_mesh((GL::NORMAL3, GL::COLOR4_UBYTE, GL::VERTEX3)), rail_mesh((GL::NORMAL3, GL::COLOR4_UBYTE, GL::VERTEX3)) { @@ -137,10 +138,15 @@ void TrackType3D::get_bounds(float angle, Point &minp, Point &maxp) const } } -void TrackType3D::render() const +void TrackType3D::render(const GL::Tag &tag) const { - ballast_mesh.draw(); - rail_mesh.draw(); + if(tag==0) + { + catalogue.get_ballast_material().bind(); + ballast_mesh.draw(); + catalogue.get_rail_material().bind(); + rail_mesh.draw(); + } } void TrackType3D::build_part(const TrackPart &part, const Profile &profile, const Point &offset, GL::MeshBuilder &bld, unsigned &base_index) diff --git a/source/3d/tracktype.h b/source/3d/tracktype.h index e0bd938..ab85d49 100644 --- a/source/3d/tracktype.h +++ b/source/3d/tracktype.h @@ -10,6 +10,7 @@ Distributed under the GPL #include #include +#include #include "libmarklin/profile.h" #include "libmarklin/tracktype.h" @@ -17,9 +18,10 @@ namespace Marklin { class Catalogue3D; -class TrackType3D +class TrackType3D: public Msp::GL::Renderable { private: + const Catalogue3D &catalogue; Msp::GL::Mesh ballast_mesh; Msp::GL::Mesh rail_mesh; std::vector border; @@ -31,7 +33,7 @@ public: void get_bounds(float, Point &, Point &) const; - void render() const; + virtual void render(const Msp::GL::Tag &) const; private: void build_part(const TrackPart &, const Profile &, const Point &, Msp::GL::MeshBuilder &, unsigned &); diff --git a/source/designer/designer.cpp b/source/designer/designer.cpp index 4763b8f..a28811f 100644 --- a/source/designer/designer.cpp +++ b/source/designer/designer.cpp @@ -40,7 +40,7 @@ Application::RegApp Designer::reg; Designer::Designer(int argc, char **argv): screen_w(1280), screen_h(960), - base_mesh(0), + base_object(0), cur_route(0), mode(SELECT), input(0), @@ -86,8 +86,8 @@ Designer::Designer(int argc, char **argv): if(!layout->get_base().empty()) { - base_mesh = new GL::Mesh; - DataFile::load(*base_mesh, layout->get_base()); + base_object = new GL::Object; + DataFile::load(*base_object, layout->get_base()); } } @@ -126,6 +126,17 @@ int Designer::main() glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_CULL_FACE); + pipeline = new GL::Pipeline(screen_w, screen_h, false); + pipeline->add_renderable(layout_3d->get_scene()); + if(base_object) + pipeline->add_renderable(*base_object); + + light.set_position(0, -0.259, 0.966, 0); + lighting.attach(0, light); + + GL::PipelinePass *pass = &pipeline->add_pass(GL::Tag()); + pass->lighting = &lighting; + DataFile::load(ui_res, "marklin.res"); root = new GLtk::Root(ui_res, *wnd); @@ -569,20 +580,18 @@ void Designer::render() { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); GL::enable(GL::DEPTH_TEST); + GL::Texture::unbind(); project_3d(); apply_camera(); if(mode==CATALOGUE) - cat_layout_3d->render(); + cat_layout_3d->get_scene().render(); else { - if(base_mesh) - { - GL::Texture::unbind(); - base_mesh->draw(); - } - layout_3d->render(true); - if(cur_route) + pipeline->render_all(); + layout_3d->get_endpoint_scene().render(); + GL::enable(GL_CULL_FACE); + /*if(cur_route) { glColor4f(0.5, 0.8, 1.0, 1.0); const set &rtracks = cur_route->get_tracks(); @@ -598,7 +607,8 @@ void Designer::render() } layout_3d->get_track(**i).render_path(path); } - } + }*/ + manipulator->render(); if(mode==MEASURE) measure->render(); diff --git a/source/designer/designer.h b/source/designer/designer.h index e103a74..1407d50 100644 --- a/source/designer/designer.h +++ b/source/designer/designer.h @@ -14,7 +14,10 @@ Distributed under the GPL #include #include #include -#include +#include +#include +#include +#include #include #include #include @@ -60,8 +63,11 @@ private: std::string filename; Marklin::Layout *layout; Marklin::Layout3D *layout_3d; - Msp::GL::Mesh *base_mesh; + Msp::GL::Object *base_object; Marklin::Route *cur_route; + Msp::GL::Pipeline *pipeline; + Msp::GL::Lighting lighting; + Msp::GL::Light light; Mode mode; Selection *selection; diff --git a/source/engineer/engineer.cpp b/source/engineer/engineer.cpp index 6a35a06..9774903 100644 --- a/source/engineer/engineer.cpp +++ b/source/engineer/engineer.cpp @@ -238,11 +238,11 @@ void Engineer::tick() //glEnable(GL_DEPTH_TEST); glEnable(GL_MULTISAMPLE); - layout_3d.render(); + layout_3d.get_scene().render(); glDisable(GL_LIGHTING); glColor4f(1, 1, 1, 1); - const list <racks = layout_3d.get_tracks(); + /*const list <racks = layout_3d.get_tracks(); for(list::const_iterator i=ltracks.begin(); i!=ltracks.end(); ++i) { Track &track = (*i)->get_track(); @@ -253,7 +253,7 @@ void Engineer::tick() } else (*i)->render_path(-1); - } + }*/ if(placing_train && placing_block) { diff --git a/source/libmarklin/profile.cpp b/source/libmarklin/profile.cpp index f4dcf18..256854b 100644 --- a/source/libmarklin/profile.cpp +++ b/source/libmarklin/profile.cpp @@ -27,7 +27,7 @@ Point Profile::get_edge_normal(unsigned i) const float dx = points[i+1].x-points[i].x; float dy = points[i+1].y-points[i].y; float len = sqrt(dx*dx+dy*dy); - return Point(-dx/len, dy/len); + return Point(dy/len, -dx/len); }