home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Linux / Divers / freedraft.tar.gz / freedraft.tar / FREEdraft-050298 / VIEWPORT / vdglcanvas.cpp < prev    next >
C/C++ Source or Header  |  1998-05-01  |  15KB  |  600 lines

  1. // vdglcanvas.cpp
  2.  
  3. // Copyright (C) 1997  Cliff Johnson                                       //
  4. //                                                                         //
  5. // This program is free software; you can redistribute it and/or           //
  6. // modify it under the terms of the GNU  General Public                    //
  7. // License as published by the Free Software Foundation; either            //
  8. // version 2 of the License, or (at your option) any later version.        //
  9. //                                                                         //
  10. // This software 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 GNU       //
  13. // General Public License for more details.                                //
  14. //                                                                         //
  15. // You should have received a copy of the GNU General Public License       //
  16. // along with this software (see COPYING.LIB); if not, write to the        //
  17. // Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. //
  18.  
  19. #include <iostream.h>
  20. #include <data_enum.h>
  21. #include <vdglcanvas.h>
  22. #include <vdcmdwin.h>
  23. #include <drawablegeom.h>
  24.  
  25. #include <point.h>
  26. #include <line.h>
  27. #include <selectstack.h>
  28. #include <vdapp_enum.h>
  29. #include <attrib_enum.h>
  30. #include <coreexception.h>
  31.  
  32.  
  33. //************************************************************************************
  34. void VDGLCanvas::LoadRegister(CanvasRegister* cr) 
  35.     canvasRegister = cr; 
  36. }
  37. //************************************************************************************
  38.  
  39.  
  40. //======================>>> testGLCanvasPane::VDGLCanvas<<<======================
  41. VDGLCanvas::VDGLCanvas(CanvasRegister* cr, unsigned int glmode): 
  42.     vBaseGLCanvasPane(glmode),
  43.     glState(Point(),1.,3.4)  // centered at zero, scale 1, 3.8 pixels/mm
  44. {
  45. // load register
  46.     canvasRegister = cr;
  47.  
  48. // set initial conditions
  49.     interfaceMode = NOMODE;
  50.     pickCount = 0;
  51.     initDone = 0;
  52. }
  53.  
  54. //======================>>> testGLCanvasPane::~VDGLCanvas<<<======================
  55. VDGLCanvas::~VDGLCanvas()
  56. {
  57. }
  58.  
  59. //======================>>> testGLCanvasPane::graphicsInit<<<======================
  60. void VDGLCanvas::graphicsInit(void)
  61. {
  62.     vBaseGLCanvasPane::graphicsInit();    // call the superclass first
  63.  
  64.     // glEnable(GL_DEPTH_TEST);
  65.     glClearDepth(1.0);
  66.     glClearColor(0.0,0.0,0.0,0.0);
  67.  
  68.     glMatrixMode(GL_PROJECTION);
  69.     glLoadIdentity();
  70.     SetOrtho2D();
  71.     glMatrixMode(GL_MODELVIEW);
  72.  
  73.     initDone = 1;
  74. }
  75.  
  76. //======================>>> testGLCanvasPane::MouseDown <<<======================
  77. void VDGLCanvas::MouseDown(int x, int y, int button)
  78. {
  79.  
  80. //cerr << "VDGLCanvas::MouseDown()" << endl;
  81.     switch(interfaceMode)
  82.     {
  83.     case PANNING:
  84.     case ZOOMIN:
  85.     case ZOOMOUT:
  86.         {
  87.         if(button != 1)break;
  88.         Point p = PickedCoord(x,y);
  89.  
  90.         pStack.Push(p);
  91.         break;
  92.         }
  93.  
  94.     case CENTERING:
  95.         {
  96.         if(button != 1)break;
  97.         glState.SetCenter(PickedCoord(x,y));
  98.             vglMakeCurrent();
  99.  
  100.         glMatrixMode(GL_PROJECTION);
  101.         glLoadIdentity();
  102.         SetOrtho2D();
  103.         glMatrixMode(GL_MODELVIEW);
  104.  
  105.         Redraw(0,0,0,0);
  106.         break;
  107.         }
  108.  
  109. //    case PICKING:
  110. //    case NOMODE:
  111. //        {
  112. //        SelectRegisteredEntities(x,y,button);
  113. //        interfaceMode = NOMODE;
  114. //        break;
  115. //        }
  116.     }
  117. // we are overriding the following:
  118. //    vBaseGLCanvasPane::MouseDown(x,y,button);
  119. }
  120.  
  121. //========================>>> VDGLCanvas::MouseUp <<<======================
  122. void VDGLCanvas::MouseUp(int x, int y, int button)
  123. {
  124.  
  125.     switch(interfaceMode)
  126.     {
  127.  
  128.     case PANNING:
  129.         {
  130.         if(button != 1)break;
  131.         Point p1 = pStack.Pop();
  132.         Point p2 = PickedCoord(x,y);
  133.         glState.SetCenter(glState.GetCenter() - p2 + p1);
  134.             vglMakeCurrent();
  135.  
  136.         glMatrixMode(GL_PROJECTION);
  137.         glLoadIdentity();
  138.         SetOrtho2D();
  139.         glMatrixMode(GL_MODELVIEW);
  140.  
  141.         Redraw(0,0,0,0);
  142.         break;
  143.         }
  144.  
  145.     case ZOOMIN:
  146.         {
  147.         if(button != 1)break;
  148.         Point p1 = pStack.Pop();
  149.         Point p2 = PickedCoord(x,y);
  150.         glState.ZoomIn(p1,p2,GetWidth(),GetHeight());
  151.             vglMakeCurrent();
  152.  
  153.         glMatrixMode(GL_PROJECTION);
  154.         glLoadIdentity();
  155.         SetOrtho2D();
  156.         glMatrixMode(GL_MODELVIEW);
  157.  
  158.         Redraw(0,0,0,0);
  159.         break;
  160.         }
  161.  
  162.     case ZOOMOUT:
  163.         {
  164.         if(button != 1)break;
  165.         Point p1 = pStack.Pop();
  166.         Point p2 = PickedCoord(x,y);
  167.         glState.ZoomOut(p1,p2,GetWidth(),GetHeight());
  168.             vglMakeCurrent();
  169.  
  170.         glMatrixMode(GL_PROJECTION);
  171.         glLoadIdentity();
  172.         SetOrtho2D();
  173.         glMatrixMode(GL_MODELVIEW);
  174.  
  175.         Redraw(0,0,0,0);
  176.         break;
  177.         }
  178.     case PICKING:
  179.     case NOMODE:
  180.         {
  181.         SelectRegisteredEntities(x,y,button);
  182.         interfaceMode = NOMODE;
  183.         break;
  184.         }
  185.     }
  186.  
  187. //   vBaseGLCanvasPane::MouseUp(x,y,button);
  188. }
  189.  
  190. //======================>>> VDGLCanvas::MouseMove <<<======================
  191. void VDGLCanvas::MouseMove(int x, int y, int button)
  192. {
  193. // animate the displacment line or selection box
  194.     switch(interfaceMode)
  195.     {
  196.  
  197.     case PANNING:
  198.         {
  199.         if(button != 1)break;
  200.         Point p1 = pStack.Top();
  201.         Point p2 = PickedCoord(x,y);
  202.             vglMakeCurrent();
  203.         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  204.         DrawRegisteredEntities();
  205.         SetAttributes(Attributes(FD_RED,FD_LINESTYLE_SOLID,1,0));
  206.             glBegin(GL_LINES);
  207.                     glVertex2f(p1[0],p1[1]);
  208.                     glVertex2f(p2[0],p2[1]);
  209.             glEnd();
  210.           vglFlush();
  211.         break;
  212.         }
  213.     case ZOOMIN:
  214.     case ZOOMOUT:
  215.         {
  216.         if(button != 1)break;
  217.         Point p1 = pStack.Top();
  218.         Point p2 = PickedCoord(x,y);
  219.             vglMakeCurrent();
  220.         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  221.         DrawRegisteredEntities();
  222.         SetAttributes(Attributes(FD_RED,FD_LINESTYLE_SOLID,1,0));
  223.         glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
  224.             glBegin(GL_POLYGON);
  225.                     glVertex2f(p1[0],p1[1]);
  226.                     glVertex2f(p2[0],p1[1]);
  227.                     glVertex2f(p2[0],p2[1]);
  228.                     glVertex2f(p1[0],p2[1]);
  229.             glEnd();
  230.         vglFlush();
  231.         break;
  232.         }
  233.     }
  234.  
  235.     vBaseGLCanvasPane::MouseMove(x,y,button);
  236. }
  237.  
  238. //=========================>>> VDGLCanvas::Redraw <<<======================
  239. void VDGLCanvas::Redraw(int x, int y, int w, int h)
  240. {
  241.     static int inRedraw = 0;
  242.  
  243.     if (inRedraw || !initDone)return;    // Don't draw until initialized
  244.  
  245.     inRedraw = 1;        // Don't allow recursive redraws.
  246.  
  247.     vglMakeCurrent();
  248.  
  249.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  250.  
  251.     DrawRegisteredEntities();
  252.  
  253.       vglFlush();
  254.  
  255.        inRedraw = 0;
  256.  
  257. }
  258.  
  259. //======================>>> virtual void VDGLCanvas::Resize <<<======================
  260. void VDGLCanvas::Resize(int w, int h)
  261. {
  262.         vBaseGLCanvasPane::Resize(w,h);
  263.  
  264.         vglMakeCurrent();
  265.  
  266.     glMatrixMode(GL_PROJECTION);
  267.     glLoadIdentity();
  268.     SetOrtho2D();
  269.     glMatrixMode(GL_MODELVIEW);
  270.  
  271.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  272.  
  273.     DrawRegisteredEntities();
  274.  
  275.       vglFlush();
  276. }
  277.  
  278. int VDGLCanvas::GetWidth()
  279. {
  280.     return vBaseGLCanvasPane::GetWidth();
  281. }
  282.  
  283. int VDGLCanvas::GetHeight()
  284. {
  285.     return vBaseGLCanvasPane::GetHeight();
  286. }
  287.  
  288. //=========================VDGLCanvas::DrawRegisteredEnttities===============
  289.  
  290. void VDGLCanvas::DrawRegisteredEntities()
  291. {
  292.  
  293. // pass through the list of handles, drawing each entity
  294.  
  295.     RegisteredEntity re;    // use a temporary copy for processing
  296.     float scale = glState.GetScale();
  297.  
  298.     if(!canvasRegister)return;          // if there is a list ( not NULL) ...
  299.  
  300.     canvasRegister->Init();    // reset the list iterator
  301.  
  302.     while(canvasRegister->NextItem(re) )
  303.     {
  304.         if(re.IsVisible())
  305.         {
  306.             if(re.IsHighlight())SetAttributes(Attributes(FD_MEDGREY,FD_LINESTYLE_SOLID,2,0));
  307.             else SetAttributes(re.GetAttributes());
  308.             re.Draw(scale);
  309.         }
  310.     }
  311. }
  312.  
  313. //=========================VDGLCanvas::SelectRegisteredEnttities===============
  314.  
  315. void VDGLCanvas::SelectRegisteredEntities(int x, int y, int button)
  316. {
  317. //cerr << "VDGLCanvas::SelectRegisteredEntities()" << endl;
  318.     RegisteredEntity re;    // use a temporary copy for processing
  319.  
  320.     if(!canvasRegister)return;    // if there is a list ( not NULL) ...
  321.  
  322. // prepare for picking 
  323.  
  324.     GLuint selectBuf[BUFSIZE];    
  325.     GLint hits;
  326.     GLint viewport[4];
  327.  
  328.     float scale = glState.GetScale();
  329.  
  330.     glGetIntegerv(GL_VIEWPORT,viewport);
  331.  
  332.     glSelectBuffer(BUFSIZE,selectBuf);
  333.     glRenderMode(GL_SELECT);
  334.  
  335.     glInitNames();
  336.     glPushName(0);
  337.  
  338.     glMatrixMode(GL_PROJECTION);
  339.     glPushMatrix();
  340.     glLoadIdentity();
  341.  
  342. // 6x6 pixel picking region near  cursor location 
  343.     gluPickMatrix(static_cast<GLfloat>(x), static_cast<GLfloat>(viewport[3] -y),
  344.     10.0,10.0,viewport);
  345.  
  346.     SetOrtho2D();
  347.  
  348. // draw the entities
  349.     canvasRegister->Init();    // reset the list iterator
  350.  
  351. // for each visible handle
  352.     while(canvasRegister->NextItem(re) ) re.Select(scale);
  353.  
  354. // collect the pick information
  355.     glMatrixMode(GL_PROJECTION);
  356.     glPopMatrix();
  357.     glFlush();
  358.  
  359.     hits = glRenderMode(GL_RENDER);
  360.  
  361.     SendCmdWindowResponse(x,y,button, hits,selectBuf);
  362. }
  363.  
  364.  
  365. //===========================================================================================
  366.  
  367.  
  368. void VDGLCanvas::SendCmdWindowResponse(int x, int y, int button, GLint hits,GLuint* selectBuf)
  369. {
  370.  
  371. //cerr << "VDGLCanvas::SendCmdWindowResponse()" << endl;
  372.  
  373. // process the selection records
  374.  
  375.     GLuint *ptr = selectBuf;
  376.     GLuint names;
  377.     RegisteredEntity re;
  378.     Handle htmp;
  379.     unsigned int hidx;
  380.  
  381.     SelectStack ss(button, PickedCoord(x,y));         // initialize selectstack
  382.  
  383.     canvasRegister->Init();    // reset the list iterator
  384.  
  385. // parse the hit records for the picked names
  386.  
  387. // for each hit...
  388.     for(int i=0; i<hits; i++){
  389.  
  390. // just skip through this stuff for our purposes
  391.         names = *ptr; // get number of names on stack when hit happened
  392.         ptr++; // to z1;
  393.         ptr++; // to z2;
  394.         ptr++; // to name lists
  395. //        for(unsigned int j=0;j<names;j++){
  396. // this name is what we want
  397. //            if(j == 0)
  398.         hidx = *ptr; // get the name (unsigned integer)
  399.         ptr++;
  400. //        } // get past this record
  401.  
  402. // find the registered entity with this handle idx - handles should be in the same order 
  403. // as in the canvas register
  404.         try
  405.         {
  406.             htmp = canvasRegister->GetHandleFromName(hidx);
  407.             ss.Push(htmp);
  408.         }
  409.         catch(CoreException & ce)
  410.         {
  411.             cerr << "CoreException Raised in VDGLCanvas::SendCmdWindowResponse()" << endl;
  412.             cerr <<  "       " << ce.what() << endl;
  413.         }
  414.     }
  415.  
  416. // all done. Send the selected handles back to the command window
  417.     (static_cast<vdCmdWindow*>(_parentWin))->CanvasPick(ss);
  418. }
  419.     
  420. //=========================VDGLCanvas::DrawLine===============
  421. //
  422. //void VDGLCanvas::DrawLine(const Line& l)
  423. //{
  424. //    //    Point p0 = Point(l.Origin()) + (10000. * Point(l.Direction()));
  425. //    //    Point p1 = Point(l.Origin()) - (10000. * Point(l.Direction()));
  426. //        Point p0 = l.Origin() + (10000. * l.Direction());
  427. //        Point p1 = l.Origin() - (10000. * l.Direction());
  428. //        glBegin(GL_LINES);
  429. //                glVertex2f(p0[0],p0[1]);
  430. //                glVertex2f(p1[0],p1[1]);
  431. //        glEnd();
  432. //}
  433. //
  434. //
  435. //----------------------VDGLCanvas::SetAttributes-----------------------
  436. void VDGLCanvas::SetAttributes(const Attributes& a) // loading a null register cancels display
  437. {
  438.     if(a == currentAttributes)return; // no reason to change anything
  439.  
  440. // we have only a small set of colors so we can implement useable selections by color
  441.  
  442.     if(!(a.GetColor() == currentAttributes.GetColor()))
  443.     {
  444.         float r,g,b;
  445.  
  446.         int colidx = a.GetColor();
  447.         r = vStdColors[colidx].r()/255.;
  448.         g = vStdColors[colidx].g()/255.;
  449.         b = vStdColors[colidx].b()/255.;
  450.         glColor3f(r,g,b);
  451.  
  452.     }
  453.  
  454.     unsigned short sx;
  455.     if(!((sx = a.GetLineStyle()) == currentAttributes.GetLineStyle()))
  456.     {
  457.     // linestippling
  458.         switch(sx)
  459.         {
  460.             case FD_LINESTYLE_SOLID:
  461.             case FD_LINESTYLE_LONGDASH:
  462.             case FD_LINESTYLE_DOTTED:
  463.                 glLineStipple(1,sx);
  464.                 break;
  465.             case FD_LINESTYLE_CHAIN:
  466.                 glLineStipple(2,sx);
  467.                 break;
  468.         }
  469.         glEnable(GL_LINE_STIPPLE);
  470.  
  471.     }
  472.     // process thicknesses  here
  473.  
  474.     if(!(a.GetThick() == currentAttributes.GetThick())){
  475.         glPointSize(a.GetThick());    
  476.         glLineWidth(a.GetThick());    
  477.     }
  478.     currentAttributes = a;
  479. }
  480.  
  481. //===========================VDGLCanvas::Register ==================
  482. //
  483. // add an entity with the window - and with the current canvasRegister
  484. //void VDGLCanvas::Register(const Handle& h, const Attributes& a, const Visibility& v)
  485. //{
  486. //    if(canvasRegister)canvasRegister->Register(h,a,v);
  487. //}
  488. //
  489. //===========================VDGLCanvas::CancelAction==================
  490.  
  491. void VDGLCanvas::CancelAction()
  492. {
  493.     interfaceMode = NOMODE;
  494.     pickCount = 0;
  495.     pStack.Clear();
  496. }
  497. //===========================VDGLCanvas::PickPan=========================
  498.  
  499. void VDGLCanvas::PickPan()
  500. {
  501.      interfaceMode = PANNING;
  502. }
  503.  
  504. //===============================VDGLCanvas::PickCenter====================
  505. void VDGLCanvas::PickCenter()
  506. {
  507.     interfaceMode = CENTERING;
  508. }
  509. //===============================VDGLCanvas::ZoomIn====================
  510. void VDGLCanvas::ZoomIn()
  511. {
  512.     interfaceMode = ZOOMIN;
  513. }
  514. //===============================VDGLCanvas::ZoomOut====================
  515. void VDGLCanvas::ZoomOut()
  516. {
  517.     interfaceMode = ZOOMOUT;
  518. }
  519. //===============================VDGLCanvas::ZoomOut====================
  520. void VDGLCanvas::ResetView()
  521. {
  522.     glState.viewCenter = Point();
  523.     glState.viewScale = 1.;
  524.     glMatrixMode(GL_PROJECTION);
  525.     glLoadIdentity();
  526.     SetOrtho2D();
  527.     glMatrixMode(GL_MODELVIEW);
  528.     Redraw(0,0,0,0);
  529. }
  530.  
  531. //void VDGLCanvas::SetGridLines(bool status, int step)
  532. //{
  533. //    drawGrid = status;
  534. //    if(drawGrid)gridStep = step;
  535. //}
  536.  
  537. //
  538. //void VDGLCanvas::DrawGridLines()
  539. //{
  540. //}
  541.  
  542. //void VDGLCanvas::LoadDrawableGeom(const DrawableGeom& dptr )
  543. //{
  544. //    for(int i=0; i< drawableRegister.size(); i++)
  545. //    {
  546. //    // replace if already in the register
  547. //        if( dptr.Type() == drawableRegister[i].Type())
  548. //        {
  549. //            drawableRegister[i] = dptr;
  550. //            return;
  551. //        }
  552. //    }
  553. //
  554. //    // not already in the list, add to the register.
  555. //    drawableRegister.push_back(dptr);
  556. //}
  557.  
  558. void VDGLCanvas::ModifyView(const vKey& keysym)
  559. {
  560. // zoom in, zoom out pan left,right,up,down
  561.     float scale = glState.GetScale();
  562.     Point center = glState.GetCenter();
  563.     float ppmm = glState.GetPPMM();
  564.     float w = GetWidth();
  565.     float h = GetHeight();
  566.  
  567.     switch(keysym)
  568.     {
  569.     //case KB_CenterView:
  570.         case KB_ZoomUp:
  571.                 glState.SetScale(scale * 1.1);
  572.         break;
  573.         case KB_ZoomDown:
  574.                 glState.SetScale(scale / 1.1);
  575.         break;
  576. // pan 10% of canvas size in each direction
  577.         case KB_LeftArrow: // geometry should move left, so the center goes to the right.
  578.         glState.SetCenter(center + Point(.1*w/(scale*ppmm),0));
  579.         break;
  580.         case KB_UpArrow:
  581.         glState.SetCenter(center - Point(0,.1*h/(scale*ppmm)));
  582.         break;
  583.         case KB_RightArrow:
  584.         glState.SetCenter(center - Point(.1*w/(scale*ppmm),0));
  585.         break;
  586.         case KB_DownArrow:
  587.         glState.SetCenter(center + Point(0,.1*h/(scale*ppmm)));
  588.         break;
  589.     }
  590.         vglMakeCurrent();
  591.  
  592.         glMatrixMode(GL_PROJECTION);
  593.         glLoadIdentity();
  594.         SetOrtho2D();
  595.         glMatrixMode(GL_MODELVIEW);
  596.  
  597.         Redraw(0,0,0,0);
  598. }
  599.