1 // Copyright (C) 2006 Erik Dahlberg
3 // This file is part of LSystem3d.
5 // LSystem3D is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
10 // LSystem3D is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with LSystem3D; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27 #include <GL/freeglut.h>
29 #include "callbacks.h"
30 #include "lindenmayersystem.h"
31 #include "lsystemparameters.h"
33 #include "openglwindow.h"
37 extern OpenGLWindow
*openglWindow
;
44 OpenGLWindow::OpenGLWindow()
49 _busyGenerating
= true;
50 lsystemParametersPath
= "lsystem.xml";
59 glutInitDisplayMode(GLUT_DOUBLE
| GLUT_RGB
| GLUT_DEPTH
);
60 glutInitWindowSize(800, 800);
61 int _window
= glutCreateWindow("lsystem");
63 // return control after closing the window
64 glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE
, 1);
67 glutKeyboardFunc(glutKeyboardCB
);
68 glutSpecialFunc(glutSpecialCB
);
69 glutDisplayFunc(glutDisplayCB
);
70 GLUI_Master
.set_glutIdleFunc(glutIdleCB
);
73 _glui
= GLUI_Master
.create_glui("lsystem");
75 // model and l-system creation
77 _lsystem
= new LindenmayerSystem(_model
);
79 // load lsystem parameters
80 _lsystemParameters
.load(_lsystem
, lsystemParametersPath
.c_str());
84 // create GLUI widgets
85 // -------------------
88 _axiomEditText
= _glui
->add_edittext("Axiom", GLUI_EDITTEXT_TEXT
);
89 _axiomEditText
->set_text((char *)_lsystem
->getAxiom().c_str());
92 // TODO: make dynamic!
93 GLUI_Panel
*panel
= _glui
->add_panel("Rules", GLUI_PANEL_EMBOSSED
);
94 _ruleEditTexts
.push_back(_glui
->add_edittext_to_panel(panel
, "#1", GLUI_EDITTEXT_TEXT
));
95 _ruleEditTexts
.push_back(_glui
->add_edittext_to_panel(panel
, "#2", GLUI_EDITTEXT_TEXT
));
96 _ruleEditTexts
.push_back(_glui
->add_edittext_to_panel(panel
, "#3", GLUI_EDITTEXT_TEXT
));
97 _ruleEditTexts
.push_back(_glui
->add_edittext_to_panel(panel
, "#4", GLUI_EDITTEXT_TEXT
));
98 _ruleEditTexts
.push_back(_glui
->add_edittext_to_panel(panel
, "#5", GLUI_EDITTEXT_TEXT
));
99 _ruleEditTexts
[0]->set_w(200);
100 _ruleEditTexts
[1]->set_w(200);
101 _ruleEditTexts
[2]->set_w(200);
102 _ruleEditTexts
[3]->set_w(200);
103 _ruleEditTexts
[4]->set_w(200);
105 // sync gui and l-system
106 map
<string
,string
> rules
= _lsystem
->getRules();
107 map
<string
,string
>::iterator currentRule
;
109 for (currentRule
= rules
.begin(); currentRule
!= rules
.end(); currentRule
++)
111 string rule
= currentRule
->first
+ "=" + currentRule
->second
;
113 _ruleEditTexts
[i
++]->set_text((char *)rule
.c_str());
117 _angleSpinner
= _glui
->add_spinner("Angle", GLUI_SPINNER_FLOAT
, NULL
, -1, (GLUI_Update_CB
)gluiSpinnerAngleCB
);
118 _angleSpinner
->set_float_val(_lsystem
->getAngle());
119 _angleSpinner
->set_speed(1.0);
122 _iterationsSpinner
= _glui
->add_spinner("Iterations", GLUI_SPINNER_INT
);
123 _iterationsSpinner
->set_int_val(_lsystem
->getNumIterations());
126 _glui
->add_separator();
131 _liveCheckbox
= _glui
->add_checkbox("Live update", &_liveUpdates
);
134 _glui
->add_button("Reset view", -1, (GLUI_Update_CB
)gluiButtonResetCB
);
137 _glui
->add_button("Generate", -1, (GLUI_Update_CB
)gluiButtonGenerateCB
);
140 _glui
->set_main_gfx_window(_window
);
149 glMatrixMode(GL_PROJECTION
);
151 gluPerspective(65, 1, 1, 100);
154 glMatrixMode(GL_MODELVIEW
);
156 gluLookAt(0.0, 0.0, 2.0,
160 glClearColor(0.0, 0.0, 0.0, 0.0);
162 glShadeModel(GL_SMOOTH
);
165 GLfloat lightPosition
[] = {0.0, 0.0, 2.0, 0.0};
166 GLfloat white
[] = {1.0, 1.0, 1.0, 1.0};
167 glLightfv(GL_LIGHT0
, GL_DIFFUSE
, white
);
168 glLightfv(GL_LIGHT0
, GL_POSITION
, lightPosition
);
170 glEnable(GL_COLOR_MATERIAL
);
171 glEnable(GL_LIGHTING
);
173 glEnable(GL_DEPTH_TEST
);
183 OpenGLWindow::~OpenGLWindow()
185 // save current l-system to disk
186 _lsystemParameters
.save(_lsystem
, lsystemParametersPath
.c_str());
195 * Start generation of l-system data
197 void OpenGLWindow::generate()
199 _busyGenerating
= true;
201 // read GLUI widgets and set corresponding l-system parameters
204 char *axiom
= _axiomEditText
->get_text();
205 _lsystem
->setAxiom(axiom
);
208 vector
<char *> rules
;
209 rules
.push_back(_ruleEditTexts
[0]->get_text());
210 rules
.push_back(_ruleEditTexts
[1]->get_text());
211 rules
.push_back(_ruleEditTexts
[2]->get_text());
212 rules
.push_back(_ruleEditTexts
[3]->get_text());
213 rules
.push_back(_ruleEditTexts
[4]->get_text());
215 for (int i
= 0; i
< rules
.size(); i
++)
217 if (rules
[i
][0] != '\0')
221 // separate rule name from the actual rule
222 string
ruleName(rules
[i
], 1);
223 string
theRule(rules
[i
]+2);
225 _lsystem
->setRule(ruleName
, theRule
);
230 float angle
= _angleSpinner
->get_float_val();
231 _lsystem
->setAngle(angle
);
234 int iterations
= _iterationsSpinner
->get_int_val();
235 _lsystem
->setNumIterations(iterations
);
240 _lsystem
->generate();
243 _busyGenerating
= false;
251 void OpenGLWindow::left()
262 void OpenGLWindow::right()
273 void OpenGLWindow::up()
284 void OpenGLWindow::down()
295 void OpenGLWindow::forth()
306 void OpenGLWindow::back()
317 void OpenGLWindow::zoomIn()
328 void OpenGLWindow::zoomOut()
337 * Rotate around y-axis
339 void OpenGLWindow::rotateY()
341 _yRotationModel
= int(_yRotationModel
+ 5.0) % 360;
348 * Draw l-system model to screen
350 void OpenGLWindow::draw()
352 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
354 if (!_busyGenerating
)
356 // ready for rendering
359 glTranslatef(_xModel
, _yModel
, _zModel
);
360 glScalef(_scaleModel
, _scaleModel
, _scaleModel
);
361 glRotatef(_yRotationModel
, 0.0, 1.0, 0.0);
373 * Reset to default view
375 void OpenGLWindow::defaultView()
377 _xModel
= _yModel
= _zModel
= 0.0;
379 _yRotationModel
= 0.0;
385 * Check if live mode is activated
386 * @return true, if activated
388 bool OpenGLWindow::liveActivated()