HeightWin.cpp

Go to the documentation of this file.
00001 //HeightWin.cpp
00002 
00003 /*************************************************************/
00004 //
00005 // HeightWinDialog
00006 //
00007 // Window for displaying the 3D heightmap
00008 //
00009 //-------------------------------------------------------------
00010 //
00011 // v 1.4 - 2007/03/31 - Changes to drawing options
00012 // v 1.3 - 2007/02/17 - Improved data output
00013 // v 1.2 - 2006/08/27 - Using near-zero rounding text output
00014 // v 1.1 - 2006/07/07 - Maximum number of grid lines
00015 // v 1.0 - 2006/04/19 - Initial release
00016 //
00017 // See LICENSE.txt for distribution and usage restrictions
00018 // Copyright (c) 2005-2007 Simon Chorley
00019 // www.mylaboratory.co.uk - greylab@mylaboratory.co.uk
00020 //
00021 /*************************************************************/
00022 
00023 
00024 ///HeightMap window (Implementation)
00025 /**
00026  * Provides implementation of HeightWinDialog class to draw the heightmap graph.
00027  * @file HeightWin.cpp
00028  * @version 1.4 - 2007/03/31
00029  */
00030 
00031 
00032 #include "HeightWin.h"
00033 
00034 #include "icons.h"
00035 #include <iostream>
00036 
00037 
00038 FXDEFMAP(HeightWinDialog) HeightWinDialogMap[] =
00039 { 
00040         //________Message_Type______________ID______________________________Message_Handler_____________
00041         FXMAPFUNC(SEL_PAINT,                            HeightWinDialog::ID_CANVAS,             HeightWinDialog::onGLExpose),
00042         FXMAPFUNC(SEL_CONFIGURE,                        HeightWinDialog::ID_CANVAS,             HeightWinDialog::onGLConfigure),
00043         FXMAPFUNC(SEL_FOCUSIN,                          HeightWinDialog::ID_CANVAS,             HeightWinDialog::onGLSelect),
00044         FXMAPFUNC(SEL_MOTION,                           HeightWinDialog::ID_CANVAS,             HeightWinDialog::onGLMouseMotion),
00045         FXMAPFUNC(SEL_LEFTBUTTONPRESS,          HeightWinDialog::ID_CANVAS,             HeightWinDialog::onGLMouseDown),
00046         FXMAPFUNC(SEL_LEFTBUTTONRELEASE,        HeightWinDialog::ID_CANVAS,             HeightWinDialog::onGLMouseUp),
00047         FXMAPFUNC(SEL_MIDDLEBUTTONPRESS,        HeightWinDialog::ID_CANVAS,             HeightWinDialog::onGLMouseDown),
00048         FXMAPFUNC(SEL_MIDDLEBUTTONRELEASE,      HeightWinDialog::ID_CANVAS,             HeightWinDialog::onGLMouseUp),
00049         FXMAPFUNC(SEL_RIGHTBUTTONPRESS,         HeightWinDialog::ID_CANVAS,             HeightWinDialog::onGLMouseDown),
00050         FXMAPFUNC(SEL_RIGHTBUTTONRELEASE,       HeightWinDialog::ID_CANVAS,             HeightWinDialog::onGLMouseUp),
00051         FXMAPFUNC(SEL_MOUSEWHEEL,                       HeightWinDialog::ID_CANVAS,             HeightWinDialog::onGLMouseWheel)
00052 }; 
00053 
00054 FXIMPLEMENT(HeightWinDialog, FXDialogBox, HeightWinDialogMap, ARRAYNUMBER(HeightWinDialogMap))
00055 
00056 
00057 ///Destructor
00058 /**
00059  * Delete data, GL canvas etc and sphere quadric.
00060  */
00061 HeightWinDialog::~HeightWinDialog()
00062 {
00063         if (sphereQuadric != NULL)
00064                 gluDeleteQuadric(sphereQuadric);
00065         if (crosshair != NULL) delete crosshair;
00066         if (hmdata != NULL) delete[] hmdata;
00067         delete GLCanvas;
00068         delete GLVisual;
00069 }
00070 
00071 
00072 ///Constructor
00073 /**
00074  * @param app Application object.
00075  * @param win Parent window.
00076  * @param ft Pointer the to the font class instance.
00077  */
00078 HeightWinDialog::HeightWinDialog(FXApp *app, FXWindow* win, CGraphFont *ft) : FXDialogBox(app, "3D Height Map", DECOR_BORDER|DECOR_RESIZE|DECOR_TITLE|DECOR_MENU|DECOR_MINIMIZE|DECOR_MAXIMIZE, 0, 0, 500, 500)
00079 {
00080         setIcon((FXIcon*)(new FXGIFIcon(app, ic_hm32, 0, IMAGE_OPAQUE)));       //set icons
00081         setMiniIcon((FXIcon*)(new FXGIFIcon(app, ic_hm16, 0, IMAGE_OPAQUE)));
00082 
00083         crosshair = NULL;
00084 
00085         GLVisual = new FXGLVisual(app, VISUAL_DOUBLEBUFFER|VISUAL_BEST|VISUAL_TRUECOLOR);       //create visual
00086         GLVisual->setAlphaSize(0);
00087         GLCanvas = new FXGLCanvas(this, GLVisual, this, ID_CANVAS, LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_TOP|LAYOUT_LEFT);
00088 
00089         crosshair = new FXCursor(app, CURSOR_CROSS);
00090         GLCanvas->setDefaultCursor(crosshair);
00091         
00092         //Initialise default settings for everything
00093         canvasSettings.fov = 60.0;
00094         canvasSettings.vp[0] = 0.01; canvasSettings.vp[1] = 100.0;
00095         canvasSettings.eye = CVector(0.0, 2.0, 0.0);
00096         canvasSettings.look = CVector(0.0, 0.5, 0.0);
00097         canvasSettings.up = CVector(0.0, 0.0, 1.0);
00098         
00099         perspective = true;
00100         box = 0;
00101         plate = true;
00102         boxcolour[0] = 0; boxcolour[1] = 0; boxcolour[2] = 0;
00103         platecolour[0] = 200; platecolour[1] = 200; platecolour[2] = 200;
00104         diffusecolour[0] = 0.5; diffusecolour[1] = 0.5; diffusecolour[2] = 0.5; diffusecolour[3] = 1.0;
00105         specularcolour[0] = 1.0; specularcolour[1] = 1.0; specularcolour[2] = 1.0; specularcolour[3] = 1.0;
00106         motiontype = false;
00107         lightpos[0] = 0.0; lightpos[1] = 1.5; lightpos[2] = 0.0; lightpos[3] = 1.0;
00108         
00109         hmdata = NULL;
00110         xdatapts = 0;
00111         ydatapts = 0;
00112 
00113         drawmode = 0;
00114         switchdir = false;
00115         zbackgrid = true;
00116         
00117         xmin.on = false;
00118         xmaj.on = false;
00119         ymin.on = false;
00120         ymaj.on = false;
00121         zmin.on = false;
00122         zmaj.on = false;
00123         
00124         mouseData[0].state = false;
00125         mouseData[1].state = false;
00126         mouseData[2].state = false;
00127 
00128         sphereQuadric = gluNewQuadric();
00129         fnt = ft;
00130 
00131 }
00132 
00133 
00134 ///Sets up the GL window and draws it for the first time
00135 /**
00136  * @param sender Object exposed that requires drawing.
00137  * @return Returns 1 to show that the message was handled.
00138  */
00139 long HeightWinDialog::onGLExpose(FXObject* sender, FXSelector, void*)
00140 {
00141         // Make context current
00142         ((FXGLCanvas*)sender)->makeCurrent();
00143 
00144         glEnable(GL_DEPTH_TEST);
00145 //      glCullFace(GL_BACK);
00146 //      glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
00147         glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
00148         glDisable(GL_DITHER);
00149 //      glEnable(GL_BLEND);
00150 //      glEnable(GL_CULL_FACE);
00151 //      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00152         glShadeModel(GL_SMOOTH);
00153 //      glLineStipple(1, 0xAAAAAAAA);
00154         glDrawBuffer(GL_BACK);
00155         glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00156         glPixelStorei(GL_PACK_ALIGNMENT, 1);
00157         glPolygonOffset(1.0, 1.0);
00158         glClearColor(1.0, 1.0, 1.0, 1.0);
00159         
00160         onGLRefresh();
00161         return(1);
00162 }
00163 
00164 
00165 ///Sets the viewport after the window is resized
00166 /**
00167  * @param sender Object that requires resizing.
00168  * @return Returns 1 to show that the message was handled.
00169  */
00170 long HeightWinDialog::onGLConfigure(FXObject* sender, FXSelector, void*)
00171 {
00172         if(((FXGLCanvas*)sender)->makeCurrent())
00173         {
00174                 glViewport(0, 0, ((FXGLCanvas*)sender)->getWidth(), ((FXGLCanvas*)sender)->getHeight());
00175                 ((FXGLCanvas*)sender)->makeNonCurrent();
00176         }
00177         return(1);
00178 }
00179 
00180 
00181 long HeightWinDialog::onGLSelect(FXObject*, FXSelector, void*)
00182 {
00183         return(1);
00184 }
00185 
00186 
00187 ///Changes the viewpoint or light position when the mouse moves
00188 /**
00189  * @param sender Object that sent the message.
00190  * @param ptr Mouse settings.
00191  * @return Returns 1 to show that the message was handled.
00192  */
00193 long HeightWinDialog::onGLMouseMotion(FXObject* sender, FXSelector, void* ptr)
00194 {
00195         FXEvent *event = (FXEvent*)ptr;
00196 
00197         int dx, dy;
00198 
00199         if (sender == GLCanvas)
00200         {
00201                 if (mouseData[0].state == true) //lmb
00202                 {
00203                         dx = event->win_x-mouseData[0].x;
00204                         dy = event->win_y-mouseData[0].y;
00205                         if (motiontype == false)        //Move camera around
00206                         {
00207                                 CVector right = (canvasSettings.look-canvasSettings.eye)*canvasSettings.up;
00208                                 right.normalise();
00209                                 canvasSettings.eye.rotate(right, (float)dy/100.0);
00210                                 canvasSettings.up.rotate(right, (float)dy/100.0);
00211                                 canvasSettings.up.normalise();
00212 
00213                                 CVector vert; vert[0] = 0.0; vert[1] = 1.0, vert[2] = 0.0;
00214                                 canvasSettings.up.rotate(vert, (float)dx/100.0);
00215                                 canvasSettings.up.normalise();
00216                                 canvasSettings.eye.rotate(vert, (float)dx/100.0);
00217                         }
00218                         else    //Move light in x-z plane
00219                         {
00220                                 CVector right = (canvasSettings.look-canvasSettings.eye)*canvasSettings.up;
00221                                 right.normalise();
00222                                 CVector forwards = right*CVector(0.0, 1.0, 0.0);
00223                                 forwards.normalise();
00224                                 forwards *= (float)dy/100.0;
00225                                 right *= (float)dx/100.0;
00226                                 lightpos[0] += forwards[0]+right[0];
00227                                 lightpos[2] += forwards[2]+right[2];
00228                         }
00229                         mouseData[0].x = event->win_x;
00230                         mouseData[0].y = event->win_y;
00231 
00232                         onGLRefresh();
00233                 }
00234                 else if (mouseData[2].state == true)    //rmb
00235                 {
00236                         dy = event->win_y-mouseData[2].y;
00237                         if (motiontype == false)        //Move camera towards and away from (0,0,0)
00238                         {
00239                                 CVector forward = canvasSettings.eye-canvasSettings.look;
00240                                 forward = canvasSettings.eye+forward*(float)dy/100.0;
00241                                 if (((forward-canvasSettings.look).mag() > 0.2) && (forward.mag() < 99.0))
00242                                         canvasSettings.eye = forward;
00243                         }
00244                         else    //Move light up and down
00245                         {
00246                                 lightpos[1] -= (float)dy/100.0;
00247                         }
00248                         mouseData[2].y = event->win_y;
00249                         onGLRefresh();
00250                 }
00251         }
00252         return(1);
00253 }
00254 
00255 
00256 ///Sets the mouse state variables when buttons pushed down
00257 /**
00258  * @param ptr Mouse settings.
00259  * @return Returns 1 to show that the message was handled.
00260  */
00261 long HeightWinDialog::onGLMouseDown(FXObject*, FXSelector, void* ptr)
00262 {
00263         FXEvent *event = (FXEvent*)ptr;
00264         mouseData[0].state = false;
00265         mouseData[1].state = false;
00266         mouseData[2].state = false;
00267         mouseData[event->click_button-1].state = true;
00268         mouseData[event->click_button-1].x = event->click_x;
00269         mouseData[event->click_button-1].y = event->click_y;
00270 
00271         return(1);
00272 }
00273 
00274 
00275 ///Resets mouse state on button up
00276 /**
00277  * @param ptr Mouse settings.
00278  * @return Returns 1 to show that the message was handled.
00279  */
00280 long HeightWinDialog::onGLMouseUp(FXObject*, FXSelector, void* ptr)
00281 {
00282         mouseData[((FXEvent*)ptr)->click_button-1].state = false;
00283         onGLRefresh();
00284         return(1);
00285 }
00286 
00287 
00288 ///Changes field of view on mouse wheel
00289 /**
00290  * @param ptr Mouse settings.
00291  * @return Returns 1 to show that the message was handled.
00292  */
00293 long HeightWinDialog::onGLMouseWheel(FXObject*, FXSelector, void* ptr)
00294 {
00295         //event code is +/-120 for wheel up/down
00296         float d = (float)(((FXEvent*)ptr)->code)/60.0;
00297         canvasSettings.fov += d;
00298         if (canvasSettings.fov < 2.0)
00299                 canvasSettings.fov = 2.0;
00300         if (canvasSettings.fov > 178.0)
00301                 canvasSettings.fov = 178.0;
00302 
00303         onGLRefresh();
00304         return(1);
00305 }
00306 
00307 
00308 ///Draws the heightmap graph
00309 void HeightWinDialog::onGLRefresh()
00310 {
00311         GLdouble width = GLCanvas->getWidth();
00312         GLdouble height = GLCanvas->getHeight();
00313         GLdouble aspect = height > 0 ? width/height : 1.0;
00314 
00315         GLCanvas->makeCurrent();
00316 
00317         //Set the viewport and perspective projection
00318         glViewport(0, 0, (int)width, (int)height);
00319         glMatrixMode(GL_PROJECTION);
00320         glLoadIdentity();
00321         if (perspective == false)
00322                 glOrtho(-aspect*0.5*(canvasSettings.vp[0]+canvasSettings.vp[1])*sin(0.25*canvasSettings.fov*PI/180.0),
00323                 aspect*0.5*(canvasSettings.vp[0]+canvasSettings.vp[1])*sin(0.25*canvasSettings.fov*PI/180.0),
00324                 -0.5*(canvasSettings.vp[0]+canvasSettings.vp[1])*sin(0.25*canvasSettings.fov*PI/180.0),
00325                 0.5*(canvasSettings.vp[0]+canvasSettings.vp[1])*sin(0.25*canvasSettings.fov*PI/180.0),
00326                 canvasSettings.vp[0], canvasSettings.vp[1]);
00327         else
00328                 gluPerspective(canvasSettings.fov, aspect, canvasSettings.vp[0], canvasSettings.vp[1]);
00329 
00330         glMatrixMode(GL_MODELVIEW);
00331         glLoadIdentity();
00332 
00333         //Clear the buffers and set the camera
00334         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
00335         gluLookAt(canvasSettings.eye[0], canvasSettings.eye[1], canvasSettings.eye[2],
00336                 canvasSettings.look[0], canvasSettings.look[1], canvasSettings.look[2],
00337                 canvasSettings.up[0], canvasSettings.up[1], canvasSettings.up[2]);
00338 
00339         //Turn off lighting
00340         float acolour[4] = {0.01, 0.01, 0.01, 1.0};
00341         glDisable(GL_COLOR_MATERIAL);
00342         glDisable(GL_LIGHTING);
00343         glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
00344         glLightfv(GL_LIGHT0, GL_AMBIENT, acolour);
00345         glLightfv(GL_LIGHT0, GL_SPECULAR, specularcolour);
00346         glLightfv(GL_LIGHT0, GL_DIFFUSE, diffusecolour);
00347         glEnable(GL_LIGHT0);
00348         float lcolour[4] = {1.0, 0.0, 1.0, 1.0};
00349         if (motiontype == true) //if in light mode draw a sphere to represtent the light
00350         {
00351                 glColor4fv(lcolour);
00352 //              cerr << 'R' << diffusecolour[0] << ',' << diffusecolour[1] << ',' << diffusecolour[2] << '\n';
00353                 glPushMatrix();
00354                         glTranslated(lightpos[0], lightpos[1], lightpos[2]);
00355                         gluSphere(sphereQuadric, 0.05, 10, 10);
00356                 glPopMatrix();
00357         }
00358         
00359         if (plate == true)      //Draw the plate if required
00360         {
00361                 glEnable(GL_POLYGON_OFFSET_FILL);       //so we don't get z-fighting with the lines
00362                 glColor3ubv(platecolour);
00363                 glBegin(GL_QUADS);
00364                         glVertex3f(-1.0, 0.0, -1.0);
00365                         glVertex3f(-1.0, 0.0, 1.0);
00366                         glVertex3f(1.0, 0.0, 1.0);
00367                         glVertex3f(1.0, 0.0, -1.0);
00368                 glEnd();
00369                 glDisable(GL_POLYGON_OFFSET_FILL);
00370         }
00371 
00372         //Get the matrix projection so we can calulate screen positions from 3D positions 
00373         GLint viewport[4];
00374         GLdouble mvmatrix[16], pmatrix[16];
00375         GLdouble px[4][3];
00376         GLdouble temppx[2][3];
00377         glGetIntegerv(GL_VIEWPORT, viewport);
00378         glGetDoublev(GL_MODELVIEW_MATRIX, mvmatrix);
00379         glGetDoublev(GL_PROJECTION_MATRIX, pmatrix);
00380         float xandz[3][2];
00381 
00382         glLineWidth(1.0);
00383         if (box == 1)   //Draw the outer box
00384         {
00385                 glColor3ubv(boxcolour);
00386                 glBegin(GL_LINES);
00387                         glVertex3f(-1.0, 0.0, -1.0);
00388                         glVertex3f(-1.0, 1.0, -1.0);
00389                         glVertex3f(-1.0, 0.0, 1.0);
00390                         glVertex3f(-1.0, 1.0, 1.0);
00391                         glVertex3f(1.0, 0.0, 1.0);
00392                         glVertex3f(1.0, 1.0, 1.0);
00393                         glVertex3f(1.0, 0.0, -1.0);
00394                         glVertex3f(1.0, 1.0, -1.0);
00395                         glVertex3f(-1.0, 1.0, -1.0);
00396                         glVertex3f(1.0, 1.0, -1.0);
00397                         glVertex3f(1.0, 1.0, -1.0);
00398                         glVertex3f(1.0, 1.0, 1.0);
00399                         glVertex3f(1.0, 1.0, 1.0);
00400                         glVertex3f(-1.0, 1.0, 1.0);
00401                         glVertex3f(-1.0, 1.0, 1.0);
00402                         glVertex3f(-1.0, 1.0, -1.0);
00403                         glVertex3f(-1.0, 0.0, 1.0);
00404                         glVertex3f(-1.0, 0.0, -1.0);
00405                         glVertex3f(-1.0, 0.0, -1.0);
00406                         glVertex3f(1.0, 0.0, -1.0);
00407                         glVertex3f(1.0, 0.0, -1.0);
00408                         glVertex3f(1.0, 0.0, 1.0);
00409                         glVertex3f(1.0, 0.0, 1.0);
00410                         glVertex3f(-1.0, 0.0, 1.0);
00411                 glEnd();
00412         }
00413         else if (box == 2)      //Draw the partial outer box
00414         {
00415                 //calculate corners
00416                 gluProject(1.0, 0.0, 1.0, mvmatrix, pmatrix, viewport, &px[0][0], &px[0][1], &px[0][2]);
00417                 gluProject(1.0, 0.0, -1.0, mvmatrix, pmatrix, viewport, &px[1][0], &px[1][1], &px[1][2]);
00418                 gluProject(-1.0, 0.0, -1.0, mvmatrix, pmatrix, viewport, &px[2][0], &px[2][1], &px[2][2]);
00419                 gluProject(-1.0, 0.0, 1.0, mvmatrix, pmatrix, viewport, &px[3][0], &px[3][1], &px[3][2]);
00420                 glColor3ubv(boxcolour);
00421                 glBegin(GL_LINES);
00422                         glVertex3f(-1.0, 0.0, 1.0);
00423                         glVertex3f(-1.0, 0.0, -1.0);
00424                         glVertex3f(-1.0, 0.0, -1.0);
00425                         glVertex3f(1.0, 0.0, -1.0);
00426                         glVertex3f(1.0, 0.0, -1.0);
00427                         glVertex3f(1.0, 0.0, 1.0);
00428                         glVertex3f(1.0, 0.0, 1.0);
00429                         glVertex3f(-1.0, 0.0, 1.0);
00430 
00431                         //work out which one is at the back
00432                         if ((px[0][1] < px[1][1]) && (px[0][1] < px[2][1]) && (px[0][1] < px[3][1]))
00433                         {
00434                                 glVertex3f(-1.0, 0.0, -1.0);
00435                                 glVertex3f(-1.0, 1.0, -1.0);
00436                                 glVertex3f(-1.0, 0.0, 1.0);
00437                                 glVertex3f(-1.0, 1.0, 1.0);
00438                                 glVertex3f(1.0, 0.0, -1.0);
00439                                 glVertex3f(1.0, 1.0, -1.0);
00440                                 glVertex3f(-1.0, 1.0, -1.0);
00441                                 glVertex3f(1.0, 1.0, -1.0);
00442                                 glVertex3f(-1.0, 1.0, 1.0);
00443                                 glVertex3f(-1.0, 1.0, -1.0);
00444                         }
00445                         else if ((px[1][1] < px[2][1]) && (px[1][1] < px[3][1]))
00446                         {
00447                                 glVertex3f(-1.0, 0.0, -1.0);
00448                                 glVertex3f(-1.0, 1.0, -1.0);
00449                                 glVertex3f(-1.0, 0.0, 1.0);
00450                                 glVertex3f(-1.0, 1.0, 1.0);
00451                                 glVertex3f(1.0, 0.0, 1.0);
00452                                 glVertex3f(1.0, 1.0, 1.0);
00453                                 glVertex3f(1.0, 1.0, 1.0);
00454                                 glVertex3f(-1.0, 1.0, 1.0);
00455                                 glVertex3f(-1.0, 1.0, 1.0);
00456                                 glVertex3f(-1.0, 1.0, -1.0);
00457                         }
00458                         else if (px[2][1] < px[3][1])
00459                         {
00460                                 glVertex3f(-1.0, 0.0, 1.0);
00461                                 glVertex3f(-1.0, 1.0, 1.0);
00462                                 glVertex3f(1.0, 0.0, 1.0);
00463                                 glVertex3f(1.0, 1.0, 1.0);
00464                                 glVertex3f(1.0, 0.0, -1.0);
00465                                 glVertex3f(1.0, 1.0, -1.0);
00466                                 glVertex3f(1.0, 1.0, -1.0);
00467                                 glVertex3f(1.0, 1.0, 1.0);
00468                                 glVertex3f(1.0, 1.0, 1.0);
00469                                 glVertex3f(-1.0, 1.0, 1.0);
00470                         }
00471                         else
00472                         {
00473                                 glVertex3f(-1.0, 0.0, -1.0);
00474                                 glVertex3f(-1.0, 1.0, -1.0);
00475                                 glVertex3f(1.0, 0.0, 1.0);
00476                                 glVertex3f(1.0, 1.0, 1.0);
00477                                 glVertex3f(1.0, 0.0, -1.0);
00478                                 glVertex3f(1.0, 1.0, -1.0);
00479                                 glVertex3f(-1.0, 1.0, -1.0);
00480                                 glVertex3f(1.0, 1.0, -1.0);
00481                                 glVertex3f(1.0, 1.0, -1.0);
00482                                 glVertex3f(1.0, 1.0, 1.0);
00483                         }
00484                 glEnd();
00485         }
00486 
00487         float p;
00488         int c;
00489         if (xmin.on == true)    //if we require a x-minor grid then draw it
00490         {
00491                 c = 0;
00492                 glColor4ubv((unsigned char*)&xmin.colour);
00493                 glBegin(GL_LINES);
00494                         p = xmin.start;
00495                         while ((p <= 1.0005) && (c < 1000))
00496                         {
00497                                 if (p >= -1.0)
00498                                 {
00499                                         glVertex3f(p, 0.0, 1.02);
00500                                         glVertex3f(p, 0.0, -1.02);
00501                                 }
00502                                 p += xmin.delta;
00503                                 ++c;    //bail out if more than 1000 lines
00504                         }
00505                 glEnd();
00506         }
00507         if (xmaj.on == true)    //similarly with the x-major
00508         {
00509                 c = 0;
00510                 glDisable(GL_DEPTH_TEST);
00511                 glColor4ubv((unsigned char*)&xmaj.colour);
00512                 glBegin(GL_LINES);
00513                         p = xmaj.start;
00514                         while ((p <= 1.0005) && (c < 1000))
00515                         {
00516                                 if (p >= -1.0)
00517                                 {
00518                                         glVertex3f(p, 0.0, 1.04);
00519                                         glVertex3f(p, 0.0, -1.04);
00520                                 }
00521                                 p += xmaj.delta;
00522                                 ++c;
00523                         }
00524                 glEnd();
00525                 glEnable(GL_DEPTH_TEST);
00526         }
00527         if (ymin.on == true)    //and other grids
00528         {
00529                 c = 0;
00530                 glColor4ubv((unsigned char*)&ymin.colour);
00531                 glBegin(GL_LINES);
00532                         p = ymin.start;
00533                         while ((p <= 1.0005) && (c < 1000))
00534                         {
00535                                 if (p >= -1.0)
00536                                 {
00537                                         glVertex3f(1.02, 0.0, p);
00538                                         glVertex3f(-1.02, 0.0, p);
00539                                 }
00540                                 p += ymin.delta;
00541                                 ++c;
00542                         }
00543                 glEnd();
00544         }
00545         if (ymaj.on == true)
00546         {
00547                 c = 0;
00548                 glDisable(GL_DEPTH_TEST);
00549                 glColor4ubv((unsigned char*)&ymaj.colour);
00550                 glBegin(GL_LINES);
00551                         p = ymaj.start;
00552                         while ((p <= 1.0005) && (c < 1000))
00553                         {
00554                                 if (p >= -1.0)
00555                                 {
00556                                         glVertex3f(1.04, 0.0, p);
00557                                         glVertex3f(-1.04, 0.0, p);
00558                                 }
00559                                 p += ymaj.delta;
00560                                 ++c;
00561                         }
00562                 glEnd();
00563                 glEnable(GL_DEPTH_TEST);
00564         }
00565         
00566         //Get the matrix projection so we can calulate screen positions from 3D positions 
00567 //      GLint viewport[4];
00568 //      GLdouble mvmatrix[16], pmatrix[16];
00569 //      GLdouble px[4][3];
00570 //      GLdouble temppx[2][3];
00571 //      glGetIntegerv(GL_VIEWPORT, viewport);
00572 //      glGetDoublev(GL_MODELVIEW_MATRIX, mvmatrix);
00573 //      glGetDoublev(GL_PROJECTION_MATRIX, pmatrix);
00574 //      float xandz[3][2];
00575         //If the z-grid is on then calculate the co-ordinates of the lines to draw
00576         if ((zmin.on == true) || (zmaj.on == true))
00577         {
00578                 //calculate corners
00579                 gluProject(1.0, 0.0, 1.0, mvmatrix, pmatrix, viewport, &px[0][0], &px[0][1], &px[0][2]);
00580                 gluProject(1.0, 0.0, -1.0, mvmatrix, pmatrix, viewport, &px[1][0], &px[1][1], &px[1][2]);
00581                 gluProject(-1.0, 0.0, -1.0, mvmatrix, pmatrix, viewport, &px[2][0], &px[2][1], &px[2][2]);
00582                 gluProject(-1.0, 0.0, 1.0, mvmatrix, pmatrix, viewport, &px[3][0], &px[3][1], &px[3][2]);
00583                 //work out which one is at the back
00584                 if ((px[0][1] < px[1][1]) && (px[0][1] < px[2][1]) && (px[0][1] < px[3][1]))
00585                 {
00586                         if (zbackgrid == true)
00587                         {
00588                                 xandz[0][0] = -1.0; xandz[0][1] = 1.0;
00589                                 xandz[1][0] = -1.0; xandz[1][1] = -1.0;
00590                                 xandz[2][0] = 1.0; xandz[2][1] = -1.0;
00591                         }
00592                         else
00593                         {
00594                                 xandz[0][0] = 0.98; xandz[0][1] = -0.98;
00595                                 xandz[1][0] = 1.02; xandz[1][1] = -1.02;
00596                                 xandz[2][0] = 1.04; xandz[2][1] = -1.04;
00597                         }
00598                 }
00599                 else if ((px[1][1] < px[2][1]) && (px[1][1] < px[3][1]))
00600                 {
00601                         if (zbackgrid == true)
00602                         {
00603                                 xandz[0][0] = 1.0; xandz[0][1] = 1.0;
00604                                 xandz[1][0] = -1.0; xandz[1][1] = 1.0;
00605                                 xandz[2][0] = -1.0; xandz[2][1] = -1.0;
00606                         }
00607                         else
00608                         {
00609                                 xandz[0][0] = -0.98; xandz[0][1] = -0.98;
00610                                 xandz[1][0] = -1.02; xandz[1][1] = -1.02;
00611                                 xandz[2][0] = -1.04; xandz[2][1] = -1.04;
00612                         }
00613                 }
00614                 else if (px[2][1] < px[3][1])
00615                 {
00616                         if (zbackgrid == true)
00617                         {
00618                                 xandz[0][0] = -1.0; xandz[0][1] = 1.0;
00619                                 xandz[1][0] = 1.0; xandz[1][1] = 1.0;
00620                                 xandz[2][0] = 1.0; xandz[2][1] = -1.0;
00621                         }
00622                         else
00623                         {
00624                                 xandz[0][0] = -0.98; xandz[0][1] = 0.98;
00625                                 xandz[1][0] = -1.02; xandz[1][1] = 1.02;
00626                                 xandz[2][0] = -1.04; xandz[2][1] = 1.04;
00627                         }
00628                 }
00629                 else
00630                 {
00631                         if (zbackgrid == true)
00632                         {
00633                                 xandz[0][0] = -1.0; xandz[0][1] = -1.0;
00634                                 xandz[1][0] = 1.0; xandz[1][1] = -1.0;
00635                                 xandz[2][0] = 1.0; xandz[2][1] = 1.0;
00636                         }
00637                         else
00638                         {
00639                                 xandz[0][0] = 0.98; xandz[0][1] = 0.98;
00640                                 xandz[1][0] = 1.02; xandz[1][1] = 1.02;
00641                                 xandz[2][0] = 1.04; xandz[2][1] = 1.04;
00642                         }
00643                 }
00644         }
00645         
00646         //Actually draw the z grid
00647         if (zmin.on == true)
00648         {
00649                 c = 0;
00650                 glColor4ubv((unsigned char*)&zmin.colour);
00651                 glBegin(GL_LINES);
00652                         p = zmin.start;
00653                         while ((p <= 1.0005) && (c < 1000))
00654                         {
00655                                 if (p >= 0.0)
00656                                 {
00657                                         if (zbackgrid == true)
00658                                         {
00659                                                 glVertex3f(xandz[0][0], p, xandz[0][1]);
00660                                                 glVertex3f(xandz[1][0], p, xandz[1][1]);
00661                                                 glVertex3f(xandz[1][0], p, xandz[1][1]);
00662                                                 glVertex3f(xandz[2][0], p, xandz[2][1]);
00663                                         }
00664                                         else
00665                                         {
00666                                                 glVertex3f(xandz[0][0], p, xandz[0][1]);
00667                                                 glVertex3f(xandz[1][0], p, xandz[1][1]);
00668                                         }
00669                                 }
00670                                 p += zmin.delta;
00671                                 ++c;
00672                         }
00673                 glEnd();
00674         }
00675         if (zmaj.on == true)
00676         {
00677                 c = 0;
00678                 glDisable(GL_DEPTH_TEST);
00679                 glColor4ubv((unsigned char*)&zmaj.colour);
00680                 glBegin(GL_LINES);
00681                         p = zmaj.start;
00682                         while ((p <= 1.0005) && (c < 1000))
00683                         {
00684                                 if (p >= 0.0)
00685                                 {
00686                                         if (zbackgrid == true)
00687                                         {
00688                                                 glVertex3f(xandz[0][0], p, xandz[0][1]);
00689                                                 glVertex3f(xandz[1][0], p, xandz[1][1]);
00690                                                 glVertex3f(xandz[1][0], p, xandz[1][1]);
00691                                                 glVertex3f(xandz[2][0], p, xandz[2][1]);
00692                                         }
00693                                         else
00694                                         {
00695                                                 glVertex3f(xandz[0][0], p, xandz[0][1]);
00696                                                 glVertex3f(xandz[2][0], p, xandz[2][1]);
00697                                         }
00698                                 }
00699                                 p += zmaj.delta;
00700                                 ++c;
00701                         }
00702                 glEnd();
00703                 glEnable(GL_DEPTH_TEST);
00704         }
00705         
00706         //Draw the data
00707         int i;
00708         float j;
00709         glEnable(GL_COLOR_MATERIAL);
00710         glEnable(GL_LIGHTING);
00711         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specularcolour);
00712         glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess);
00713         glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
00714 //      cerr << ydatapts << ',' << xdatapts << '\n';
00715         if (ydatapts*xdatapts > 0)
00716         {
00717                 //set up the clip planes
00718                 double plane[4] = {0.0, 1.0, 0.0, 0.0};
00719                 glClipPlane(GL_CLIP_PLANE0, plane);     //bottom
00720                 plane[1] = -1.0; plane[3] = 1.0;
00721                 glClipPlane(GL_CLIP_PLANE1, plane); //top
00722                 plane[0] = 1.0; plane[1] = 0.0;
00723                 glClipPlane(GL_CLIP_PLANE2, plane);
00724                 plane[0] = -1.0; //plane[3] = 1.0;
00725                 glClipPlane(GL_CLIP_PLANE3, plane);
00726                 plane[0] = 0.0; plane[2] = -1.0;
00727                 glClipPlane(GL_CLIP_PLANE4, plane);
00728                 plane[2] = 1.0; //plane[3] = 1.0;
00729                 glClipPlane(GL_CLIP_PLANE5, plane);
00730 
00731                 glEnable(GL_CLIP_PLANE0);
00732                 glEnable(GL_CLIP_PLANE1);
00733                 glEnable(GL_CLIP_PLANE2);
00734                 glEnable(GL_CLIP_PLANE3);
00735                 glEnable(GL_CLIP_PLANE4);
00736                 glEnable(GL_CLIP_PLANE5);
00737                 //Draw
00738                 if (switchdir == false)
00739                 {
00740                         for (i = 0; i < (ydatapts-1); ++i)
00741                         {
00742                                 if (drawmode == 0)
00743                                         glBegin(GL_TRIANGLE_STRIP);
00744                                 else if (drawmode == 1)
00745                                         glBegin(GL_LINES);
00746                                 else
00747                                         glBegin(GL_POINTS);
00748                                 for (j = 0.0; j < (float)xdatapts; j += (float)xdatapts/(float)xdatadisplay)
00749                                 {
00750                                         if (((int)(j+0.5) < xdatapts) && ((1+i) < ydatapts))
00751                                         {
00752                                                 glColor3ubv(hmdata[(int)(j+0.5)+xdatapts*i].colour);
00753                                                 glNormal3fv(hmdata[(int)(j+0.5)+xdatapts*i].normal);
00754                                                 glVertex3fv(hmdata[(int)(j+0.5)+xdatapts*i].position);
00755                                                 glColor3ubv(hmdata[(int)(j+0.5)+xdatapts*(1+i)].colour);
00756                                                 glNormal3fv(hmdata[(int)(j+0.5)+xdatapts*(1+i)].normal);
00757                                                 glVertex3fv(hmdata[(int)(j+0.5)+xdatapts*(1+i)].position);
00758                                         }
00759                                 }
00760                                 if ((int)(j+0.5) > (xdatapts-1))
00761                                 {
00762                                                 glColor3ubv(hmdata[(xdatapts-1)+xdatapts*i].colour);
00763                                                 glNormal3fv(hmdata[(xdatapts-1)+xdatapts*i].normal);
00764                                                 glVertex3fv(hmdata[(xdatapts-1)+xdatapts*i].position);
00765                                                 glColor3ubv(hmdata[(xdatapts-1)+xdatapts*(1+i)].colour);
00766                                                 glNormal3fv(hmdata[(xdatapts-1)+xdatapts*(1+i)].normal);
00767                                                 glVertex3fv(hmdata[(xdatapts-1)+xdatapts*(1+i)].position);
00768                                 }
00769 /*                              for (j = 0.0; j < (float)xdatapts; j += (float)xdatapts/(float)xdatadisplay)
00770                                 {
00771                                         glColor3ubv(hmdata[(int)(j+0.5)+xdatapts*i].colour);
00772                                         glNormal3fv(hmdata[(int)(j+0.5)+xdatapts*i].normal);
00773                                         glVertex3fv(hmdata[(int)(j+0.5)+xdatapts*i].position);
00774                                         glColor3ubv(hmdata[(int)(j+0.5)+xdatapts*(1+i)].colour);
00775                                         glNormal3fv(hmdata[(int)(j+0.5)+xdatapts*(1+i)].normal);
00776                                         glVertex3fv(hmdata[(int)(j+0.5)+xdatapts*(1+i)].position);
00777                                 }
00778                                 if ((j-(float)xdatapts/(float)xdatadisplay) < xdatapts-1)
00779                                 {
00780                                                 glColor3ubv(hmdata[(xdatapts-1)+xdatapts*i].colour);
00781                                                 glNormal3fv(hmdata[(xdatapts-1)+xdatapts*i].normal);
00782                                                 glVertex3fv(hmdata[(xdatapts-1)+xdatapts*i].position);
00783                                                 glColor3ubv(hmdata[(xdatapts-1)+xdatapts*(1+i)].colour);
00784                                                 glNormal3fv(hmdata[(xdatapts-1)+xdatapts*(1+i)].normal);
00785                                                 glVertex3fv(hmdata[(xdatapts-1)+xdatapts*(1+i)].position);
00786                                 }*/
00787                                 glEnd();
00788                         }
00789                 }
00790                 else
00791                 {
00792                         int jprime;
00793                         for (j = 0.0; j < (float)xdatapts; j += (float)xdatapts/(float)xdatadisplay)
00794                         {
00795                                 if (drawmode == 0)
00796                                         glBegin(GL_TRIANGLE_STRIP);
00797                                 else if (drawmode == 1)
00798                                         glBegin(GL_LINES);
00799                                 else
00800                                         glBegin(GL_POINTS);
00801                                 jprime = (int)(j+0.5+(float)xdatapts/(float)xdatadisplay);
00802                                 if (jprime > xdatapts-1)
00803                                         jprime = xdatapts-1;
00804                                 if (j < xdatapts-1)
00805                                 {
00806                                         for (i = 0; i < ydatapts; ++i)
00807                                         {
00808                                                 glColor3ubv(hmdata[jprime+xdatapts*i].colour);
00809                                                 glNormal3fv(hmdata[jprime+xdatapts*i].normal);
00810                                                 glVertex3fv(hmdata[jprime+xdatapts*i].position);
00811                                                 glColor3ubv(hmdata[(int)(j+0.5)+xdatapts*i].colour);
00812                                                 glNormal3fv(hmdata[(int)(j+0.5)+xdatapts*i].normal);
00813                                                 glVertex3fv(hmdata[(int)(j+0.5)+xdatapts*i].position);
00814                                         }
00815                                 }
00816                                 glEnd();
00817                         }
00818 /*                      if ((j-(float)xdatapts/(float)xdatadisplay) < xdatapts-1)
00819                         {
00820                                 if (drawmode == 0)
00821                                         glBegin(GL_TRIANGLE_STRIP);
00822                                 else if (drawmode == 1)
00823                                         glBegin(GL_LINES);
00824                                 else
00825                                         glBegin(GL_POINTS);
00826                                 for (i = 0; i < ydatapts; ++i)
00827                                 {
00828                                         glColor3ubv(hmdata[(xdatapts-1)+xdatapts*i].colour);
00829                                         glNormal3fv(hmdata[(xdatapts-1)+xdatapts*i].normal);
00830                                         glVertex3fv(hmdata[(xdatapts-1)+xdatapts*i].position);
00831                                         glColor3ubv(hmdata[(int)(j+0.5-(float)xdatapts/(float)xdatadisplay)+xdatapts*i].colour);
00832                                         glNormal3fv(hmdata[(int)(j+0.5-(float)xdatapts/(float)xdatadisplay)+xdatapts*i].normal);
00833                                         glVertex3fv(hmdata[(int)(j+0.5-(float)xdatapts/(float)xdatadisplay)+xdatapts*i].position);
00834                                 }
00835                                 glEnd();
00836                         }*/
00837                 }
00838                 glDisable(GL_CLIP_PLANE0);
00839                 glDisable(GL_CLIP_PLANE1);
00840                 glDisable(GL_CLIP_PLANE2);
00841                 glDisable(GL_CLIP_PLANE3);
00842                 glDisable(GL_CLIP_PLANE4);
00843                 glDisable(GL_CLIP_PLANE5);
00844         }
00845 
00846 
00847 #define CHARGAP 10
00848 #define NORMALISE temppx[0][0] -= temppx[1][0]; temppx[0][1] -= temppx[1][1]; m = sqrt(temppx[0][0]*temppx[0][0]+temppx[0][1]*temppx[0][1]); temppx[0][0] *= CHARGAP/m; temppx[0][1] *= CHARGAP/m;
00849 
00850         //If no mouse buttons are pushed draw the text labels
00851         if ((mouseData[0].state == false) && (mouseData[1].state == false) && (mouseData[2].state == false))
00852         {
00853                 if (drawlabels == 1)
00854                 {
00855 #define L_YMAX 0
00856 #define L_YMIN 1
00857 #define L_YLBL 2
00858 #define L_XMAX 3
00859 #define L_XMIN 4
00860 #define L_XLBL 5
00861 #define L_ZMAX 6
00862 #define L_ZMIN 7
00863 #define L_ZLBL 8
00864 #define L_TIT 9
00865 #define L_STIT 10
00866                         //Calculate the size of each string
00867                         int labeldims[11][3];   //ymax, ymin, ylabel, x versions, z versions, title, subtitle (length, x, y)
00868                         labeldims[L_YMAX][0] = fnt->getStringDimensions(FXDoubleVal(axes[2]));
00869                         labeldims[L_YMIN][0] = fnt->getStringDimensions(FXDoubleVal(axes[3]));
00870                         labeldims[L_YLBL][0] = fnt->getStringDimensions(labels[3]);
00871 //                      if (ylabelrotCheckbutton->getCheck() == false)
00872 //                              leftlegend = CHARGAP+largest(labeldims[0], labeldims[1], labeldims[2]); //longest y string
00873 //                      else
00874 //                              leftlegend = CHARGAP+largest(labeldims[0], labeldims[1], fnt->fontheight);      //longest y string
00875                         labeldims[L_XMAX][0] = fnt->getStringDimensions(FXDoubleVal(axes[1]));
00876                         labeldims[L_XMIN][0] = fnt->getStringDimensions(FXDoubleVal(axes[0]));
00877                         labeldims[L_XLBL][0] = fnt->getStringDimensions(