From: spixx Date: Sat, 4 Nov 2006 19:28:58 +0000 (+0000) Subject: initial version X-Git-Url: https://git.piment-noir.org/?a=commitdiff_plain;h=3025996ba17bf59f5bc64def5d55b95c4d732a8a;p=lsystem3d.git initial version --- diff --git a/src/color.cpp b/src/color.cpp new file mode 100644 index 0000000..3d45ed8 --- /dev/null +++ b/src/color.cpp @@ -0,0 +1,92 @@ +// Copyright (C) 2006 Erik Dahlberg +// +// This file is part of LSystem3d. +// +// LSystem3D is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// LSystem3D is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with LSystem3D; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + + + +#include "color.h" + + + +/** + * Constructor + * @param r red component + * @param g green component + * @param b blue component + */ +Color::Color(double r, double g, double b) +{ + setRGB(r, g, b); +} + + + +/** + * Destructor + */ +Color::~Color() +{ +} + + + +/** + * Set color + * @param r red component + * @param g green component + * @param b blue component + */ +void Color::setRGB(double r, double g, double b) +{ + _r = r; + _g = g; + _b = b; +} + + + +/** + * Get red component + * @return the red component + */ +double Color::getR() +{ + return _r; +} + + + +/** + * Get green component + * @return the green component + */ +double Color::getG() +{ + return _g; +} + + + +/** + * Get blue component + * @return the blue component + */ +double Color::getB() +{ + return _b; +} diff --git a/src/color.h b/src/color.h new file mode 100644 index 0000000..b186464 --- /dev/null +++ b/src/color.h @@ -0,0 +1,80 @@ +// Copyright (C) 2006 Erik Dahlberg +// +// This file is part of LSystem3d. +// +// LSystem3D is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// LSystem3D is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with LSystem3D; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + + + +#ifndef COLOR_H +#define COLOR_H + + + +/** + * Color in RGB format + */ +class Color +{ +public: + + /** + * Constructor + * @param r red component + * @param g green component + * @param b blue component + */ + Color(double r, double g, double b); + + /** + * Destructor + */ + ~Color(); + + /** + * Set color + * @param r red component + * @param g green component + * @param b blue component + */ + void setRGB(double r, double g, double b); + + /** + * Get red component + * @return the red component + */ + double getR(); + + /** + * Get green component + * @return the green component + */ + double getG(); + + /** + * Get blue component + * @return the blue component + */ + double getB(); + +protected: + + double _r, _g, _b; +}; + + + +#endif diff --git a/src/gui.cpp b/src/gui.cpp new file mode 100644 index 0000000..d068cd5 --- /dev/null +++ b/src/gui.cpp @@ -0,0 +1,211 @@ +// Copyright (C) 2006 Erik Dahlberg +// +// This file is part of LSystem3d. +// +// LSystem3D is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// LSystem3D is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with LSystem3D; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + + + +#include +#include + +#include "fx.h" + +#include "gui.h" +#include "lindenmayersystem.h" +#include "lsystemparameters.h" +#include "renderingsurface.h" + + + +// message map +FXDEFMAP(GUI) GUIMap[] = +{ + FXMAPFUNC(SEL_COMMAND, GUI::ID_GENERATE, GUI::onGenerateButtonPressed) +}; + +// macro to set up class implementation +FXIMPLEMENT(GUI, FXMainWindow, GUIMap, ARRAYNUMBER(GUIMap)) + + + +/** + * Constructor + * @param application the FOX application object + * @param renderingSurface the rendering surface + * @param lsystem the Lindenmayer-system + */ +GUI::GUI(FXApp *application, RenderingSurface *renderingSurface, LindenmayerSystem *lsystem) : FXMainWindow(application, "LSystem3D" , NULL, NULL, DECOR_ALL, 920, 100, 0, 0) +{ + _lsystem = lsystem; + _renderingSurface = renderingSurface; + + + // create the widgets + + // the main frame + FXVerticalFrame *mainFrame = new FXVerticalFrame(this, LAYOUT_FILL_X); + + // axiom + FXHorizontalFrame *axiomFrame = new FXHorizontalFrame(mainFrame, LAYOUT_FILL_X); + new FXLabel(axiomFrame, "Axiom:"); + _axiomTextField = new FXTextField(axiomFrame, 10, NULL, 0, LAYOUT_FILL_X); + + // rules + FXHorizontalFrame *rulesFrame = new FXHorizontalFrame(mainFrame, LAYOUT_FILL_X); + new FXLabel(rulesFrame, "Rules:"); + _rulesText = new FXText(rulesFrame, NULL, 0, LAYOUT_FILL_X); + _rulesText->setVisibleColumns(30); + _rulesText->setVisibleRows(10); + + // angle + FXHorizontalFrame *angleFrame = new FXHorizontalFrame(mainFrame); + new FXLabel(angleFrame, "Angle:"); + _angleRealSpinner = new FXRealSpinner(angleFrame, 5); + + // iterations + FXHorizontalFrame *iterationsFrame = new FXHorizontalFrame(mainFrame); + new FXLabel(iterationsFrame, "Iterations:"); + _iterationsSpinner = new FXSpinner(iterationsFrame, 5); + + // diameter + FXHorizontalFrame *diameterFrame = new FXHorizontalFrame(mainFrame); + new FXLabel(diameterFrame, "Diameter:"); + _diameterRealSpinner = new FXRealSpinner(diameterFrame, 5); + _diameterRealSpinner->setValue(0.2); + _diameterRealSpinner->setIncrement(0.1); + + // diameter factor + new FXLabel(diameterFrame, "Factor:"); + _diameterFactorRealSpinner = new FXRealSpinner(diameterFrame, 5); + _diameterFactorRealSpinner->setValue(0.8); + _diameterFactorRealSpinner->setIncrement(0.1); + + // separator + new FXHorizontalSeparator(mainFrame, SEPARATOR_RIDGE | LAYOUT_FILL_X); + + // generate + new FXButton(mainFrame, "&Generate", NULL, this, GUI::ID_GENERATE); + + + + // load L-system parameters from file and sync with GUI + + _lsystemParameters.load(_lsystem, "lsystem.xml"); + + // axiom + _axiomTextField->setText(_lsystem->getAxiom().c_str()); + + // rules + map allRulesSrc = _lsystem->getRules(); + string allRulesDst; + for (map::iterator currentRule = allRulesSrc.begin(); + currentRule != allRulesSrc.end(); + currentRule++) + { + // one rule + string rule = currentRule->first + "=" + currentRule->second + '\n'; + allRulesDst += rule.c_str(); + } + _rulesText->setText(allRulesDst.c_str(), allRulesDst.size()); + + // angle + _angleRealSpinner->setValue(_lsystem->getAngle()); + + // iterations + _iterationsSpinner->setValue(_lsystem->getNumIterations()); +} + + + +/** + * Create and initialize the window + */ +void GUI::create() +{ + // create the window and make it appear + FXMainWindow::create(); + show(); +} + + + +/** + * Called by the system when the "generate"-button is pressed + * @param sender the sender object + * @param selector message type and id + * @param data event related data + * @return + */ +long GUI::onGenerateButtonPressed(FXObject *sender, FXSelector selector, void *data) +{ + // clear L-system + _lsystem->clear(); + + + // load data from widgets into L-system + + // axiom + _lsystem->setAxiom(_axiomTextField->getText().text()); + + // rules + string ruleSet = _rulesText->getText().text(); + string currentRule; + string ruleName; + bool newRule = true; + for (int i = 0; i < ruleSet.size(); i++) + { + if (newRule) + { + // get rule name + ruleName = ruleSet[i]; + i += 2; + newRule = false; + } + + if (ruleSet[i] != '\n' || i == ruleSet.size() - 1) + { + // part of current rule + currentRule += ruleSet[i]; + } + + if (ruleSet[i] == '\n' || i == ruleSet.size() - 1) + { + // end of rule + _lsystem->setRule(ruleName, currentRule); + ruleName.clear(); + currentRule.clear(); + newRule = true; + } + } + + // angle + _lsystem->setAngle(_angleRealSpinner->getValue()); + + // iterations + _lsystem->setNumIterations(_iterationsSpinner->getValue()); + + // diameter + _lsystem->setDiameter(_diameterRealSpinner->getValue()); + + // diameter factor + _lsystem->setDiameterFactor(_diameterFactorRealSpinner->getValue()); + + + // generate and render L-system to screen + _lsystem->generate(); + _renderingSurface->draw(); +} diff --git a/src/gui.h b/src/gui.h new file mode 100644 index 0000000..b5664c8 --- /dev/null +++ b/src/gui.h @@ -0,0 +1,99 @@ +// Copyright (C) 2006 Erik Dahlberg +// +// This file is part of LSystem3d. +// +// LSystem3D is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// LSystem3D is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with LSystem3D; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + + + +#ifndef GUI_H +#define GUI_H + +#include "fx.h" + +#include "lindenmayersystem.h" +#include "lsystemparameters.h" +#include "renderingsurface.h" + + + +/** + * The GUI window + */ +class GUI : public FXMainWindow +{ + // macro to set up class declaration + FXDECLARE(GUI) + +public: + + // message ID's + enum + { + ID_GENERATE = FXMainWindow::ID_LAST, + ID_LAST + }; + + /** + * Constructor + * @param application the FOX application object + * @param renderingSurface the rendering surface + * @param lsystem the Lindenmayer-system + */ + GUI(FXApp *application, RenderingSurface *renderingSurface, LindenmayerSystem *lsystem); + + /** + * Create and initialize the window + */ + void create(); + + /** + * Called by the system when the "generate"-button is pressed + * @param sender the sender object + * @param selector message type and id + * @param data event related data + * @return + */ + long onGenerateButtonPressed(FXObject *sender, FXSelector selector, void *data); + +protected: + + /** + * Constructor + */ + GUI() {} + +private: + + // GUI widgets + + FXTextField *_axiomTextField; // Axiom + FXText *_rulesText; // Rules + FXRealSpinner *_angleRealSpinner; // Angle + FXSpinner *_iterationsSpinner; // Iterations + + FXRealSpinner *_diameterRealSpinner; // Diameter + FXRealSpinner *_diameterFactorRealSpinner; // Diameter factor //TODO: "diameter factor"? + + + LindenmayerSystem *_lsystem; // The Lindenmayer-system + LSystemParameters _lsystemParameters; // Saves/loads l-system parameters from file + RenderingSurface *_renderingSurface; // The rendering surface +}; + + + +#endif diff --git a/src/lsystem3d.cpp b/src/lsystem3d.cpp new file mode 100644 index 0000000..f485826 --- /dev/null +++ b/src/lsystem3d.cpp @@ -0,0 +1,58 @@ +// Copyright (C) 2006 Erik Dahlberg +// +// This file is part of LSystem3d. +// +// LSystem3D is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// LSystem3D is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with LSystem3D; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + + + +#include "fx.h" + +#include "gui.h" +#include "lindenmayersystem.h" +#include "lsystem3d.h" +#include "model.h" +#include "renderingsurface.h" + + + +/** + * Constructor + */ +LSystem3D::LSystem3D(int argc, char *argv[]) +{ + // create the FOX application object + FXApp *application = new FXApp("LSystem3D"); + application->init(argc, argv); + + Model model; + LindenmayerSystem lsystem(&model); + + // create the windows and run the application + RenderingSurface *surface = new RenderingSurface(application, &lsystem); + new GUI(application, surface, &lsystem); + application->create(); + application->run(); +} + + + +/** + * Destructor + */ +LSystem3D::~LSystem3D() +{ +} diff --git a/src/lsystem3d.h b/src/lsystem3d.h new file mode 100644 index 0000000..c750f1e --- /dev/null +++ b/src/lsystem3d.h @@ -0,0 +1,47 @@ +// Copyright (C) 2006 Erik Dahlberg +// +// This file is part of LSystem3d. +// +// LSystem3D is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// LSystem3D is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with LSystem3D; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + + + +#ifndef LSYSTEM3D_H +#define LSYSTEM3D_H + + + +/** + * The main class + */ +class LSystem3D +{ +public: + + /** + * Constructor + */ + LSystem3D(int argc, char *argv[]); + + /** + * Destructor + */ + ~LSystem3D(); +}; + + + +#endif diff --git a/src/renderingsurface.cpp b/src/renderingsurface.cpp new file mode 100644 index 0000000..8da174d --- /dev/null +++ b/src/renderingsurface.cpp @@ -0,0 +1,310 @@ +// Copyright (C) 2006 Erik Dahlberg +// +// This file is part of LSystem3d. +// +// LSystem3D is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// LSystem3D is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with LSystem3D; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + + + +#include +#include + +#include "fx.h" +#include "fx3d.h" + +#include "renderingsurface.h" + + + +// message map +FXDEFMAP(RenderingSurface) RenderingSurfaceMap[] = +{ + FXMAPFUNC(SEL_LEFTBUTTONPRESS, RenderingSurface::ID_CANVAS, RenderingSurface::onLeftMouseDown), + FXMAPFUNC(SEL_LEFTBUTTONRELEASE, RenderingSurface::ID_CANVAS, RenderingSurface::onLeftMouseUp), + FXMAPFUNC(SEL_MIDDLEBUTTONPRESS, RenderingSurface::ID_CANVAS, RenderingSurface::onMiddleMouseDown), + FXMAPFUNC(SEL_MIDDLEBUTTONRELEASE, RenderingSurface::ID_CANVAS, RenderingSurface::onMiddleMouseUp), + FXMAPFUNC(SEL_RIGHTBUTTONPRESS, RenderingSurface::ID_CANVAS, RenderingSurface::onRightMouseDown), + FXMAPFUNC(SEL_RIGHTBUTTONRELEASE, RenderingSurface::ID_CANVAS, RenderingSurface::onRightMouseUp), + FXMAPFUNC(SEL_MOTION, RenderingSurface::ID_CANVAS, RenderingSurface::onMouseMove), + FXMAPFUNC(SEL_PAINT, RenderingSurface::ID_CANVAS, RenderingSurface::onRepaint) +}; + +// macro to set up class implementation +FXIMPLEMENT(RenderingSurface, FXMainWindow, RenderingSurfaceMap, ARRAYNUMBER(RenderingSurfaceMap)) + + + +/** + * Constructor + * @param application the FOX application object + * @param lsystem the Lindenmayer-system + */ +RenderingSurface::RenderingSurface(FXApp *application, LindenmayerSystem *lsystem) : FXMainWindow(application, "LSystem3D", NULL, NULL, DECOR_ALL, 100, 100, 800, 800) +{ + _lsystem = lsystem; + + _modelX = 0.0; + _modelY = 0.0; + _modelZ = -10.0; + + _modelRotationY = 0.0; + + _leftMouseDown = _rightMouseDown = _middleMouseDown = false; + + + // pixel format info + _visual = new FXGLVisual(getApp(), VISUAL_DOUBLEBUFFER); + + // OpenGL drawing area + FXVerticalFrame *mainFrame = new FXVerticalFrame(this, LAYOUT_FILL_X | LAYOUT_FILL_Y); + _canvas = new FXGLCanvas(mainFrame, _visual, this, ID_CANVAS, LAYOUT_FILL_X | LAYOUT_FILL_Y); +} + + + +/** + * Create and initialize the window + */ +void RenderingSurface::create() +{ + // create the window + FXMainWindow::create(); + + // set up OpenGL + _canvas->makeCurrent(); + initOpenGL(); + + // make the window appear + show(); +} + + + +/** + * Initialize OpenGL + */ +void RenderingSurface::initOpenGL() +{ + // projection matrix + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(65, 1, 1, 500); + + // modelview matrix + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + + // global ambient light + GLfloat ambientLight[] = {0.7, 0.7, 0.7, 1.0}; + glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight); + + // diffuse light + GLfloat lightPosition[] = {150.0, 150.0, 0.0, 0.0}; + GLfloat whiteLight[] = {1.0, 1.0, 1.0, 1.0}; + glLightfv(GL_LIGHT0, GL_DIFFUSE, whiteLight); + glLightfv(GL_LIGHT0, GL_POSITION, lightPosition); + + + glEnable(GL_COLOR_MATERIAL); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glEnable(GL_DEPTH_TEST); +} + + + +/** + * Force an update of the rendering surface + */ +void RenderingSurface::draw() +{ + _canvas->update(); +} + + + +/** + * Called by the system when the left mouse button is pressed + * @param sender the sender object + * @param selector message type and id + * @param data event related data + * @return + */ +long RenderingSurface::onLeftMouseDown(FXObject *sender, FXSelector selector, void *data) +{ + _leftMouseDown = true; +} + + + +/** + * Called by the system when the left mouse button is released + * @param sender the sender object + * @param selector message type and id + * @param data event related data + * @return + */ +long RenderingSurface::onLeftMouseUp(FXObject *sender, FXSelector selector, void *data) +{ + _leftMouseDown = false; +} + + + +/** + * Called by the system when the middle mouse button is pressed + * @param sender the sender object + * @param selector message type and id + * @param data event related data + * @return + */ +long RenderingSurface::onMiddleMouseDown(FXObject *sender, FXSelector selector, void *data) +{ + _middleMouseDown = true; +} + + + +/** + * Called by the system when the middle mouse button is released + * @param sender the sender object + * @param selector message type and id + * @param data event related data + * @return + */ +long RenderingSurface::onMiddleMouseUp(FXObject *sender, FXSelector selector, void *data) +{ + _middleMouseDown = false; +} + + + +/** + * Called by the system when the right mouse button is pressed + * @param sender the sender object + * @param selector message type and id + * @param data event related data + * @return + */ +long RenderingSurface::onRightMouseDown(FXObject *sender, FXSelector selector, void *data) +{ + _rightMouseDown = true; +} + + + +/** + * Called by the system when the right mouse button is released + * @param sender the sender object + * @param selector message type and id + * @param data event related data + * @return + */ +long RenderingSurface::onRightMouseUp(FXObject *sender, FXSelector selector, void *data) +{ + _rightMouseDown = false; +} + + + +/** + * Called by the system when the mouse is moved + * @param sender the sender object + * @param selector message type and id + * @param data event related data + * @return + */ +long RenderingSurface::onMouseMove(FXObject *sender, FXSelector selector, void *data) +{ + // check status of the mouse buttons and move model + + // left mouse button + if (_leftMouseDown) + { + // move in z-plane + + FXEvent *event = (FXEvent*)data; + + // TODO: "gluPerspective(65, 1, 1, 500)" -> "translateFactor = 610.0 / (-_modelZ)", ugly... + double translateFactor = 610.0 / (-_modelZ); + + _modelX += (event->win_x - event->last_x) / translateFactor; + _modelY += -(event->win_y - event->last_y) / translateFactor; + + _canvas->update(); + } + + // middle mouse button + if (_middleMouseDown) + { + // zoom in/out + + FXEvent *event = (FXEvent*)data; + + _modelZ += -(event->win_y - event->last_y) / 10.0; + + // stop zooming at -1.0 + if (_modelZ >= -1.0) + { + _modelZ = -1.0; + } + + _canvas->update(); + } + + // right mouse button + if (_rightMouseDown) + { + // rotate around y-axis + + FXEvent *event = (FXEvent*)data; + + _modelRotationY = ((int)_modelRotationY + event->win_x - event->last_x) % 360; + + _canvas->update(); + } +} + + + +/** + * Called by the system when the rendering surface needs a repaint + * @param sender the sender object + * @param selector message type and id + * @param data event related data + * @return + */ +long RenderingSurface::onRepaint(FXObject *sender, FXSelector selector, void *data) +{ + glMatrixMode (GL_MODELVIEW); + glLoadIdentity(); + + + // clear scene + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // position and orientation of model + glTranslatef(_modelX, _modelY, _modelZ); + glRotatef(_modelRotationY, 0.0, 1.0, 0.0); + + // render model + _lsystem->getModel()->draw(); + + + // make it appear + _canvas->swapBuffers(); +} diff --git a/src/renderingsurface.h b/src/renderingsurface.h new file mode 100644 index 0000000..d6e8f16 --- /dev/null +++ b/src/renderingsurface.h @@ -0,0 +1,173 @@ +// Copyright (C) 2006 Erik Dahlberg +// +// This file is part of LSystem3d. +// +// LSystem3D is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// LSystem3D is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with LSystem3D; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + + + +#ifndef RENDERINGSURFACE_H +#define RENDERINGSURFACE_H + +#include "fx.h" +#include "fx3d.h" + +#include "lindenmayersystem.h" + + + +/** + * The OpenGL rendering surface + */ +class RenderingSurface : public FXMainWindow +{ + // macro to set up class declaration + FXDECLARE(RenderingSurface) + +public: + + // message ID's + enum + { + ID_CANVAS = FXMainWindow::ID_LAST, + ID_LAST + }; + + /** + * Constructor + * @param application the FOX application object + * @param lsystem the Lindenmayer-system + */ + RenderingSurface(FXApp *application, LindenmayerSystem *lsystem); + + /** + * Create and initialize the window + */ + void create(); + + /** + * Initialize OpenGL + */ + void initOpenGL(); + + /** + * Force an update of the rendering surface + */ + void draw(); + + /** + * Called by the system when the left mouse button is pressed + * @param sender the sender object + * @param selector message type and id + * @param data event related data + * @return + */ + long onLeftMouseDown(FXObject *sender, FXSelector selector, void *data); + + /** + * Called by the system when the left mouse button is released + * @param sender the sender object + * @param selector message type and id + * @param data event related data + * @return + */ + long onLeftMouseUp(FXObject *sender, FXSelector selector, void *data); + + /** + * Called by the system when the middle mouse button is pressed + * @param sender the sender object + * @param selector message type and id + * @param data event related data + * @return + */ + long onMiddleMouseDown(FXObject *sender, FXSelector selector, void *data); + + /** + * Called by the system when the middle mouse button is released + * @param sender the sender object + * @param selector message type and id + * @param data event related data + * @return + */ + long onMiddleMouseUp(FXObject *sender, FXSelector selector, void *data); + + /** + * Called by the system when the right mouse button is pressed + * @param sender the sender object + * @param selector message type and id + * @param data event related data + * @return + */ + long onRightMouseDown(FXObject *sender, FXSelector selector, void *data); + + /** + * Called by the system when the right mouse button is released + * @param sender the sender object + * @param selector message type and id + * @param data event related data + * @return + */ + long onRightMouseUp(FXObject *sender, FXSelector selector, void *data); + + /** + * Called by the system when the mouse is moved + * @param sender the sender object + * @param selector message type and id + * @param data event related data + * @return + */ + long onMouseMove(FXObject *sender, FXSelector selector, void *data); + + /** + * Called by the system when the rendering surface needs a repaint + * @param sender the sender object + * @param selector message type and id + * @param data event related data + * @return + */ + long onRepaint(FXObject *sender, FXSelector selector, void *data); + +protected: + + /** + * Constructor + */ + RenderingSurface() {} + +private: + + FXGLVisual *_visual; // Pixel format info + FXGLCanvas *_canvas; // OpenGL-capable drawing area + + LindenmayerSystem *_lsystem; // The Lindenmayer System + + // Model position + double _modelX, + _modelY, + _modelZ; + + // Model rotation + double _modelRotationY; + + // Mouse button status + bool _leftMouseDown, + _middleMouseDown, + _rightMouseDown; +}; + + + +#endif