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
28 #include "renderingsurface.h"
33 FXDEFMAP(RenderingSurface
) RenderingSurfaceMap
[] =
35 FXMAPFUNC(SEL_LEFTBUTTONPRESS
, RenderingSurface::ID_CANVAS
, RenderingSurface::onLeftMouseDown
),
36 FXMAPFUNC(SEL_LEFTBUTTONRELEASE
, RenderingSurface::ID_CANVAS
, RenderingSurface::onLeftMouseUp
),
37 FXMAPFUNC(SEL_MIDDLEBUTTONPRESS
, RenderingSurface::ID_CANVAS
, RenderingSurface::onMiddleMouseDown
),
38 FXMAPFUNC(SEL_MIDDLEBUTTONRELEASE
, RenderingSurface::ID_CANVAS
, RenderingSurface::onMiddleMouseUp
),
39 FXMAPFUNC(SEL_RIGHTBUTTONPRESS
, RenderingSurface::ID_CANVAS
, RenderingSurface::onRightMouseDown
),
40 FXMAPFUNC(SEL_RIGHTBUTTONRELEASE
, RenderingSurface::ID_CANVAS
, RenderingSurface::onRightMouseUp
),
41 FXMAPFUNC(SEL_MOTION
, RenderingSurface::ID_CANVAS
, RenderingSurface::onMouseMove
),
42 FXMAPFUNC(SEL_PAINT
, RenderingSurface::ID_CANVAS
, RenderingSurface::onRepaint
)
45 // macro to set up class implementation
46 FXIMPLEMENT(RenderingSurface
, FXMainWindow
, RenderingSurfaceMap
, ARRAYNUMBER(RenderingSurfaceMap
))
52 * @param application the FOX application object
53 * @param lsystem the Lindenmayer-system
55 RenderingSurface::RenderingSurface(FXApp
*application
, LindenmayerSystem
*lsystem
) : FXMainWindow(application
, "LSystem3D", NULL
, NULL
, DECOR_ALL
, 100, 100, 800, 800)
63 _modelRotationY
= 0.0;
65 _leftMouseDown
= _rightMouseDown
= _middleMouseDown
= false;
69 _visual
= new FXGLVisual(getApp(), VISUAL_DOUBLEBUFFER
);
71 // OpenGL drawing area
72 FXVerticalFrame
*mainFrame
= new FXVerticalFrame(this, LAYOUT_FILL_X
| LAYOUT_FILL_Y
);
73 _canvas
= new FXGLCanvas(mainFrame
, _visual
, this, ID_CANVAS
, LAYOUT_FILL_X
| LAYOUT_FILL_Y
);
79 * Create and initialize the window
81 void RenderingSurface::create()
84 FXMainWindow::create();
87 _canvas
->makeCurrent();
90 // make the window appear
99 void RenderingSurface::initOpenGL()
102 glMatrixMode(GL_PROJECTION
);
104 gluPerspective(65, 1, 1, 500);
107 glMatrixMode(GL_MODELVIEW
);
111 // global ambient light
112 GLfloat ambientLight
[] = {0.7, 0.7, 0.7, 1.0};
113 glLightModelfv(GL_LIGHT_MODEL_AMBIENT
, ambientLight
);
116 GLfloat lightPosition
[] = {150.0, 150.0, 0.0, 0.0};
117 GLfloat whiteLight
[] = {1.0, 1.0, 1.0, 1.0};
118 glLightfv(GL_LIGHT0
, GL_DIFFUSE
, whiteLight
);
119 glLightfv(GL_LIGHT0
, GL_POSITION
, lightPosition
);
122 glEnable(GL_COLOR_MATERIAL
);
123 glEnable(GL_LIGHTING
);
125 glEnable(GL_DEPTH_TEST
);
131 * Force an update of the rendering surface
133 void RenderingSurface::draw()
141 * Called by the system when the left mouse button is pressed
142 * @param sender the sender object
143 * @param selector message type and id
144 * @param data event related data
147 long RenderingSurface::onLeftMouseDown(FXObject
*sender
, FXSelector selector
, void *data
)
149 _leftMouseDown
= true;
155 * Called by the system when the left mouse button is released
156 * @param sender the sender object
157 * @param selector message type and id
158 * @param data event related data
161 long RenderingSurface::onLeftMouseUp(FXObject
*sender
, FXSelector selector
, void *data
)
163 _leftMouseDown
= false;
169 * Called by the system when the middle mouse button is pressed
170 * @param sender the sender object
171 * @param selector message type and id
172 * @param data event related data
175 long RenderingSurface::onMiddleMouseDown(FXObject
*sender
, FXSelector selector
, void *data
)
177 _middleMouseDown
= true;
183 * Called by the system when the middle mouse button is released
184 * @param sender the sender object
185 * @param selector message type and id
186 * @param data event related data
189 long RenderingSurface::onMiddleMouseUp(FXObject
*sender
, FXSelector selector
, void *data
)
191 _middleMouseDown
= false;
197 * Called by the system when the right mouse button is pressed
198 * @param sender the sender object
199 * @param selector message type and id
200 * @param data event related data
203 long RenderingSurface::onRightMouseDown(FXObject
*sender
, FXSelector selector
, void *data
)
205 _rightMouseDown
= true;
211 * Called by the system when the right mouse button is released
212 * @param sender the sender object
213 * @param selector message type and id
214 * @param data event related data
217 long RenderingSurface::onRightMouseUp(FXObject
*sender
, FXSelector selector
, void *data
)
219 _rightMouseDown
= false;
225 * Called by the system when the mouse is moved
226 * @param sender the sender object
227 * @param selector message type and id
228 * @param data event related data
231 long RenderingSurface::onMouseMove(FXObject
*sender
, FXSelector selector
, void *data
)
233 // check status of the mouse buttons and move model
240 FXEvent
*event
= (FXEvent
*)data
;
242 // TODO: "gluPerspective(65, 1, 1, 500)" -> "translateFactor = 610.0 / (-_modelZ)", ugly...
243 double translateFactor
= 610.0 / (-_modelZ
);
245 _modelX
+= (event
->win_x
- event
->last_x
) / translateFactor
;
246 _modelY
+= -(event
->win_y
- event
->last_y
) / translateFactor
;
251 // middle mouse button
252 if (_middleMouseDown
)
256 FXEvent
*event
= (FXEvent
*)data
;
258 _modelZ
+= -(event
->win_y
- event
->last_y
) / 10.0;
260 // stop zooming at -1.0
269 // right mouse button
272 // rotate around y-axis
274 FXEvent
*event
= (FXEvent
*)data
;
276 _modelRotationY
= ((int)_modelRotationY
+ event
->win_x
- event
->last_x
) % 360;
285 * Called by the system when the rendering surface needs a repaint
286 * @param sender the sender object
287 * @param selector message type and id
288 * @param data event related data
291 long RenderingSurface::onRepaint(FXObject
*sender
, FXSelector selector
, void *data
)
293 glMatrixMode (GL_MODELVIEW
);
298 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
300 // position and orientation of model
301 glTranslatef(_modelX
, _modelY
, _modelZ
);
302 glRotatef(_modelRotationY
, 0.0, 1.0, 0.0);
305 _lsystem
->getModel()->draw();
309 _canvas
->swapBuffers();