home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / oct93 / graphics / graphtal.lha / Graphtal / FlatDevice.C < prev    next >
C/C++ Source or Header  |  1992-11-17  |  6KB  |  242 lines

  1. /*
  2.  * FlatDevice.C - zBuffer device driver.
  3.  *
  4.  * Copyright (C) 1992, Christoph Streit (streit@iam.unibe.ch)
  5.  *                     University of Berne, Switzerland
  6.  * All rights reserved.
  7.  *
  8.  * This software may be freely copied, modified, and redistributed
  9.  * provided that this copyright notice is preserved on all copies.
  10.  *
  11.  * You may not distribute this software, in whole or in part, as part of
  12.  * any commercial product without the express consent of the authors.
  13.  *
  14.  * There is no warranty or other guarantee of fitness of this software
  15.  * for any purpose.  It is provided solely "as is".
  16.  *
  17.  */
  18.  
  19. #include "FlatDevice.h"
  20. #include "Polygon.h"
  21. #include "Sphere.h"
  22.  
  23. static const int defaultConeResolution = 5;
  24. static const int defaultSphereResolution = 4;
  25.  
  26. //___________________________________________________________ PolyWithColor
  27.  
  28. class PolyWithColor {
  29. friend class FlatDevice;
  30. public:
  31.   PolyWithColor()
  32.   : p(NULL) {}
  33.   PolyWithColor(Polygon* poly, const Color& color)
  34.   : p(poly), c(color) {}
  35.   ~PolyWithColor() { if (p) delete p; }
  36.  
  37. private:
  38.   Polygon* p;
  39.   Color c;
  40. };
  41.  
  42. typedef PolyWithColor* PolyWithColorPtr;
  43. declareList(PolyWithColorList, PolyWithColorPtr);
  44. implementList(PolyWithColorList, PolyWithColorPtr);
  45.  
  46. //___________________________________________________________ FlatDevice
  47.  
  48. FlatDevice::FlatDevice(Options* options)
  49. : DeviceDriver(options), polys(NULL)
  50. {
  51.   coneResolution = (theOptions->coneResolution <= 0) 
  52.     ? defaultConeResolution
  53.     : theOptions->coneResolution;
  54.   sphereResolution = (theOptions->sphereResolution <= 0) 
  55.     ? defaultSphereResolution
  56.     : theOptions->sphereResolution;
  57.  
  58.   /*
  59.    * Make up table for cone generation.
  60.    */
  61.   sintable = new real[coneResolution];
  62.   costable = new real[coneResolution];
  63.  
  64.   real alpha;
  65.   for (register int i=0; i<coneResolution; i++) {
  66.     alpha = (2*M_PI*i)/coneResolution;
  67.     SinCos(alpha, sintable[i], costable[i]);
  68.   }
  69.   top = new Vector[coneResolution];
  70.   bottom = new Vector[coneResolution];
  71.   
  72.   /*
  73.    * Generate unit sphere.
  74.    */
  75.   unitSphere = Sphere::tesselation(Vector(0,0,0), 1, sphereResolution);
  76.  
  77.   /*
  78.    * Initialize z-buffer renderer
  79.    */
  80.   zBuffer = new Z_Buffer(new ViewTransform(theOptions->eye, 
  81.                        theOptions->lookat, 
  82.                        theOptions->up, theOptions->fov,
  83.                        theOptions->resX, theOptions->resY),
  84.              "Image rendered with graphtal",
  85.              theOptions->oname);
  86. }
  87.  
  88. FlatDevice::~FlatDevice()
  89. {
  90.   delete [] sintable;
  91.   delete [] costable;
  92.   delete [] top;
  93.   delete [] bottom;
  94.  
  95.   for (register long i=0; i<unitSphere->count(); i++)
  96.     delete unitSphere->item(i);
  97.   delete unitSphere;
  98.  
  99.   delete zBuffer;
  100.  
  101.   StringTable_Iterator macroItr(macroNames);
  102.   while(macroItr.more()){
  103.     PolyWithColorList* polyList = (PolyWithColorList*) macroItr.cur_value();
  104.     for (i = 0; i<polyList->count(); i++)
  105.       delete polyList->item(i);
  106.     delete polyList;
  107.     macroItr.next();
  108.   } 
  109. }
  110.  
  111. void FlatDevice::begin(){}
  112.  
  113. void FlatDevice::end(const BoundingBox&)
  114. {
  115.   if (theOptions->verbose)
  116.     cerr << "primitives: "<< zBuffer->primitives() << '\n';
  117.  
  118.   zBuffer->writePixmap();
  119. }
  120.  
  121. void FlatDevice::cylinder(const Vector& p1, const Vector& p2, real r)
  122. {
  123.   cone(p1, r, p2, r);
  124. }
  125.  
  126. void FlatDevice::cone(const Vector& p1, real r1, const Vector& p2, real r2)
  127. {
  128.   Vector axis = p2 - p1;
  129.  
  130.   /*
  131.    * Degenerated cone?
  132.    */
  133.   if (axis.normalize() == 0)
  134.     return;
  135.  
  136.   Vector u, v;
  137.  
  138.   /*
  139.    * Find 2 vectors normal to cone axis and to each other.
  140.    */
  141.   u[0] = -axis[1]; u[1] =  axis[0]; u[2] = 0;
  142.   if (u.normalize() == 0) {
  143.     u[0] = axis[2]; u[1] = 0;  u[2] = -axis[0];
  144.     u.normalize();
  145.   }
  146.   v = axis*u;
  147.  
  148.   Vector d;
  149.   for (register int i=0; i<coneResolution; i++) {
  150.     d = costable[i]*u + sintable[i]*v;
  151.     *(bottom+i) = p1 + d*r1;
  152.     *(top+i)    = p2 + d*r2;   
  153.   }
  154.         
  155.   for (i=0; i<coneResolution; i++) {
  156.     if (definingMacro) {
  157.       Polygon* p = new Polygon(*(bottom+i), *(top+i), 
  158.                    *(top+((i+1)%coneResolution)), 
  159.                    *(bottom+((i+1)%coneResolution)));
  160.       PolyWithColor* pwc = new PolyWithColor(p, currentColor);
  161.       polys->append(pwc);
  162.     }
  163.     else
  164.       zBuffer->renderRectangle(currentColor,
  165.                    *(bottom+i), *(top+i), 
  166.                    *(top+((i+1)%coneResolution)), 
  167.                    *(bottom+((i+1)%coneResolution)));
  168.   }
  169. }
  170.  
  171. void FlatDevice::polygon(Polygon* p)
  172. {
  173.   if (definingMacro) {
  174.     PolyWithColor* pwc = new PolyWithColor(p, currentColor);
  175.     polys->append(pwc);
  176.   }
  177.   else 
  178.     zBuffer->renderPolygon(currentColor, p);
  179. }
  180.  
  181. void FlatDevice::sphere(const Vector& pos, real r)
  182. {
  183.   /*
  184.    * Transform the unit sphere to radius r and position pos.
  185.    */
  186.   for (register long i=0; i<unitSphere->count(); i++) {
  187.     Polygon* p = unitSphere->item(i);
  188.     Polygon* transformedPoly = new Polygon(p->numVertices());
  189.     for (register long j=0; j<p->numVertices(); j++)
  190.       transformedPoly->addVertex(p->vertex(j)*r+pos); 
  191.  
  192.     if (definingMacro) {
  193.       PolyWithColor* pwc = new PolyWithColor(transformedPoly, currentColor);
  194.       polys->append(pwc);
  195.     }
  196.     else
  197.       zBuffer->renderPolygon(currentColor, transformedPoly);
  198.   }
  199. }
  200.  
  201. void FlatDevice::color(const Color& color)
  202. {
  203.   currentColor = color;
  204. }
  205.  
  206. void FlatDevice::beginMacro(const rcString& macroName)
  207. {
  208.   definingMacro = 1;
  209.   currentMacroName = macroName;
  210.   polys = new PolyWithColorList(100);
  211. }
  212.  
  213. void FlatDevice::endMacro()
  214. {
  215.   definingMacro = 0;
  216.   macroNames.find_and_replace(currentMacroName, polys);
  217.   polys = NULL;
  218. }
  219.  
  220. void FlatDevice::executeMacro(const rcString& macroName, 
  221.                   const TransMatrix& tmat)
  222. {
  223.   anyPtr argument;
  224.   if (!macroNames.lookup(macroName, argument))
  225.     Error(ERR_PANIC, "FlatDevice::executeMacro: macro " 
  226.                  + macroName + " does not exist");
  227.  
  228.   PolyWithColorList* polyList = (PolyWithColorList*) argument;
  229.   for (register long i=0; i<polyList->count(); i++) {
  230.     Polygon* p = new Polygon(*polyList->item(i)->p);
  231.     p->transform(tmat);
  232.  
  233.     if (definingMacro) {
  234.       PolyWithColor* pwc = new PolyWithColor(p, polyList->item(i)->c);
  235.       polys->append(pwc);
  236.     }
  237.     else
  238.       zBuffer->renderPolygon(polyList->item(i)->c, p);
  239.   }
  240. }
  241.  
  242.