From abb9de15be1ad022a288827ffbcdb01e94ac3eb8 Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Mon, 18 Jan 2010 07:42:46 +0000 Subject: [PATCH] Render an actual L-system tree! --- src/LTree.cpp | 90 ++++++++++++++++++++++++++++++++++++++--------- src/LTreeDemo.cpp | 10 +++++- 2 files changed, 83 insertions(+), 17 deletions(-) diff --git a/src/LTree.cpp b/src/LTree.cpp index a9baa2c..8a0ed8a 100644 --- a/src/LTree.cpp +++ b/src/LTree.cpp @@ -22,14 +22,21 @@ #include #include #include +#include +#include +#include + +#include namespace lsystem { enum Token { X = 'X', // Only used for replacement F = 'F', // Draw forward - L = 'L', // Turn left N degrees - R = 'R', // Turn right N degrees + L = '-', // Turn left N degrees + R = '+', // Turn right N degrees + B = '[', // Push position + E = ']', // Pop position }; typedef list TokenList; @@ -62,7 +69,6 @@ namespace lsystem { ostream_iterator(os)); return os; } - } lsystem::Rule::Rule(Token lhs, const char* tokenStr) @@ -72,7 +78,6 @@ lsystem::Rule::Rule(Token lhs, const char* tokenStr) rhs.push_back((Token)*tokenStr++); } - lsystem::LSystem::LSystem(const Rule* rules, int nRules, Token start) : rules(rules), nRules(nRules), start(start) { @@ -101,6 +106,8 @@ void lsystem::evolve(LSystem& l) } while (it != l.state.end()); } +using namespace lsystem; + // Trees generated by L-systems class LTree : public IScenery { public: @@ -110,28 +117,79 @@ public: void render() const; void setPosition(float x, float y, float z); private: + struct RenderState { + RenderState() + : x(0.0f), y(0.0f), z(0.0f) + {} + + float x, y, z; + }; + + void interpret(Token t, RenderState& rs) const; + + LSystem ls; + + static const Rule rules[]; +}; + +const Rule LTree::rules[] = { + Rule(X, "F-[[X]+X]+F[+FX]-X"), + Rule(F, "FF"), }; LTree::LTree() + : ls(rules, 2, X) { - using namespace lsystem; - - Rule rules[] = { - Rule(X, "F-[[X]+X]+F[+FX]-X"), - Rule(F, "FF"), - }; - LSystem l(rules, 2, X); - - debug() << "Initial: " << l; + debug() << "Initial: " << ls; for (int n = 0; n < 5; n++) { - evolve(l); - debug() << "n=" << n << ": " << l; + evolve(ls); + debug() << "n=" << n << ": " << ls; } } -void LTree::render() const +void LTree::interpret(Token t, RenderState& rs) const { + const float SEGMENT_LEN = 0.01f; + + switch (t) { + case 'F': + glBegin(GL_LINES); + glVertex3f(0.0f, 0.0f, 0.0f); + glVertex3f(0.0f, SEGMENT_LEN, 0.0f); + glEnd(); + glTranslatef(0.0f, SEGMENT_LEN, 0.0f); + break; + case 'X': + // Ignored + break; + case '-': + glRotatef(25.0, 0.0f, 0.0f, 1.0f); + break; + case '+': + glRotatef(-25.0, 0.0f, 0.0f, 1.0f); + break; + case '[': + glPushMatrix(); + break; + case ']': + glPopMatrix(); + break; + default: + { + ostringstream ss; + ss << "Bad token in LTree: " << static_cast(t); + throw runtime_error(ss.str()); + } + } +} +void LTree::render() const +{ + using namespace placeholders; + + RenderState rs; + for_each(ls.state.begin(), ls.state.end(), + bind(<ree::interpret, this, _1, rs)); } void LTree::setPosition(float x, float y, float z) diff --git a/src/LTreeDemo.cpp b/src/LTreeDemo.cpp index da40114..89ff054 100644 --- a/src/LTreeDemo.cpp +++ b/src/LTreeDemo.cpp @@ -19,6 +19,8 @@ #include "ILogger.hpp" #include "IScenery.hpp" +#include + class LTreeDemo : public IScreen { public: LTreeDemo(); @@ -37,16 +39,22 @@ public: MouseButton button) {} private: + ISceneryPtr ltree; }; LTreeDemo::LTreeDemo() { - makeLTree(); + ltree = makeLTree(); } void LTreeDemo::display(IGraphicsPtr context) const { + glDisable(GL_LIGHTING); + glDisable(GL_TEXTURE_2D); + + glTranslatef(0.0f, 0.0f, -5.0f); + ltree->render(); } void LTreeDemo::overlay() const -- 2.39.2