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
),
43 FXMAPFUNC(SEL_CLOSE
, 0, RenderingSurface::onQuit
)
46 // macro to set up class implementation
47 FXIMPLEMENT(RenderingSurface
, FXMainWindow
, RenderingSurfaceMap
, ARRAYNUMBER(RenderingSurfaceMap
))
53 * @param application the application object
55 RenderingSurface::RenderingSurface(FXApp
*application
) : 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
);
81 RenderingSurface::~RenderingSurface()
89 * Create and initialize the window
91 void RenderingSurface::create()
94 FXMainWindow::create();
97 _canvas
->makeCurrent();
101 // make the window appear
110 void RenderingSurface::initOpenGL()
113 glMatrixMode(GL_PROJECTION
);
115 gluPerspective(65, 1, 1, 500);
118 glMatrixMode(GL_MODELVIEW
);
122 // global ambient light
123 GLfloat ambientLight
[] = {0.7, 0.7, 0.7, 1.0};
124 glLightModelfv(GL_LIGHT_MODEL_AMBIENT
, ambientLight
);
127 GLfloat lightPosition
[] = {150.0, 150.0, 0.0, 0.0};
128 GLfloat whiteLight
[] = {1.0, 1.0, 1.0, 1.0};
129 glLightfv(GL_LIGHT0
, GL_DIFFUSE
, whiteLight
);
130 glLightfv(GL_LIGHT0
, GL_POSITION
, lightPosition
);
133 glEnable(GL_COLOR_MATERIAL
);
134 glEnable(GL_LIGHTING
);
136 glEnable(GL_DEPTH_TEST
);
142 * Force an update of the rendering surface
144 void RenderingSurface::draw()
152 * Called by the system when the left mouse button is pressed
153 * @param sender the sender object
154 * @param selector message type and id
155 * @param data event related data
158 long RenderingSurface::onLeftMouseDown(FXObject
*sender
, FXSelector selector
, void *data
)
160 _leftMouseDown
= true;
166 * Called by the system when the left mouse button is released
167 * @param sender the sender object
168 * @param selector message type and id
169 * @param data event related data
172 long RenderingSurface::onLeftMouseUp(FXObject
*sender
, FXSelector selector
, void *data
)
174 _leftMouseDown
= false;
180 * Called by the system when the middle mouse button is pressed
181 * @param sender the sender object
182 * @param selector message type and id
183 * @param data event related data
186 long RenderingSurface::onMiddleMouseDown(FXObject
*sender
, FXSelector selector
, void *data
)
188 _middleMouseDown
= true;
194 * Called by the system when the middle mouse button is released
195 * @param sender the sender object
196 * @param selector message type and id
197 * @param data event related data
200 long RenderingSurface::onMiddleMouseUp(FXObject
*sender
, FXSelector selector
, void *data
)
202 _middleMouseDown
= false;
208 * Called by the system when the right mouse button is pressed
209 * @param sender the sender object
210 * @param selector message type and id
211 * @param data event related data
214 long RenderingSurface::onRightMouseDown(FXObject
*sender
, FXSelector selector
, void *data
)
216 _rightMouseDown
= true;
222 * Called by the system when the right mouse button is released
223 * @param sender the sender object
224 * @param selector message type and id
225 * @param data event related data
228 long RenderingSurface::onRightMouseUp(FXObject
*sender
, FXSelector selector
, void *data
)
230 _rightMouseDown
= false;
236 * Called by the system when the mouse is moved
237 * @param sender the sender object
238 * @param selector message type and id
239 * @param data event related data
242 long RenderingSurface::onMouseMove(FXObject
*sender
, FXSelector selector
, void *data
)
244 // check status of the mouse buttons and move model
251 FXEvent
*event
= (FXEvent
*)data
;
253 // TODO: "gluPerspective(65, 1, 1, 500)" -> "translateFactor = 610.0 / (-_modelZ)", ugly...
254 double translateFactor
= 610.0 / (-_modelZ
);
256 _modelX
+= (event
->win_x
- event
->last_x
) / translateFactor
;
257 _modelY
+= -(event
->win_y
- event
->last_y
) / translateFactor
;
262 // middle mouse button
263 if (_middleMouseDown
)
267 FXEvent
*event
= (FXEvent
*)data
;
269 _modelZ
+= -(event
->win_y
- event
->last_y
) / 10.0;
271 // stop zooming at -1.0
280 // right mouse button
283 // rotate around y-axis
285 FXEvent
*event
= (FXEvent
*)data
;
287 _modelRotationY
= ((int)_modelRotationY
+ event
->win_x
- event
->last_x
) % 360;
296 * Called by the system when the rendering surface needs a repaint
297 * @param sender the sender object
298 * @param selector message type and id
299 * @param data event related data
302 long RenderingSurface::onRepaint(FXObject
*sender
, FXSelector selector
, void *data
)
304 glMatrixMode (GL_MODELVIEW
);
309 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
311 // position and orientation of model
312 glTranslatef(_modelX
, _modelY
, _modelZ
);
313 glRotatef(_modelRotationY
, 0.0, 1.0, 0.0);
319 _canvas
->swapBuffers();
325 * Called by the system when the close button is pressed
326 * @param sender the sender object
327 * @param selector message type and id
328 * @param data event related data
331 long RenderingSurface::onQuit(FXObject
*sender
, FXSelector selector
, void *data
)
341 * Set current L-system generator
342 * @param lsystem the L-system generator
344 void RenderingSurface::setLSystem(LindenmayerSystem
*lsystem
)