home *** CD-ROM | disk | FTP | other *** search
/ Photo CD Demo 1 / Demo.bin / graphtal / flatdevc.c < prev    next >
C/C++ Source or Header  |  1992-11-02  |  6KB  |  241 lines

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