home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 064.lha / antialias.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-11-20  |  7.4 KB  |  276 lines

  1.  
  2. /* fundamental custom window opening program */
  3. /* based upon the program in "INSIDE Amiga Graphics" */
  4.  
  5. #include <exec/types.h>          /* All the standard garbage */
  6. #include <intuition/intuition.h>
  7. #include <graphics/gfxmacros.h>
  8. #include <functions.h>
  9.  
  10. struct IntuitionBase *IntuitionBase;    /* And our wonderful libraries */
  11. struct GfxBase *GfxBase;
  12. struct IntuiMessage *message;
  13.  
  14. struct Screen *Scr;            /* Our very own custom Screen     */
  15. struct Window *Wdw;            /*  and Window             */
  16. struct ViewPort *WVP;            /*  and ViewPort structures    */
  17.  
  18. ULONG MessageClass;            /* If we want messages from Intuition*/
  19. USHORT code;                /*  these will be handy        */    
  20.  
  21. #define Rp   Wdw->RPort            /* And this will save some typing */
  22.  
  23. long multi, divis;    /* These will specify our pixel coverage ratios  */
  24. int polycolor = 15;    /* This will specify our polygon Pen color      */
  25.  
  26. PLANEPTR workspace;    /* We'll need a workspace and TmpRas for filling */
  27. struct TmpRas myTmpRas;    /*  the Amiga's standard circles */
  28.  
  29. static USHORT colormap [16] =
  30. {
  31.    0x000,0x110,0x220,0x330,0x440,0x550,0x660,0x770,0x880,
  32.    0x990,0xAA0,0xBB0,0xCC0,0xDD0,0xEE0,0xFF0   
  33. };    /* This is our range of colors from black to full yellow */
  34.  
  35. struct TextAttr StdFont =    /* Font structure */
  36.    {
  37.     "topaz.font",
  38.     TOPAZ_EIGHTY,
  39.     FS_NORMAL,
  40.     FPF_ROMFONT,
  41.    };
  42.  
  43.  
  44. struct NewScreen NewScr =    /* for our custom screen - 4 bit planes */
  45.    {
  46.     0,0,        /* Left Edge, Top Edge */
  47.     320,200,
  48.     4,
  49.     1,0,
  50.     NULL,
  51.     CUSTOMSCREEN,
  52.     &StdFont,
  53.     "Test Screen",
  54.     NULL,
  55.     NULL
  56.    };
  57.  
  58. struct NewWindow NewWdw =    /* full screen window for drawing in */
  59.    {
  60.     0,0,        /* Left Edge, Top Edge */
  61.     320,200,    /* Width, Height */
  62.     0,5,         /* Block Pen, Detail Pen */
  63.     CLOSEWINDOW ,    /* IDCMP Flags */
  64.     SMART_REFRESH | ACTIVATE | WINDOWCLOSE,  /* Flags */
  65.     NULL,        /* Pointer to First Gadget */
  66.     NULL,        /* Pointer to Checkmark image */
  67.     "Anti-Aliasing Demo by Miles Kurland",     /* Title */
  68.     NULL,        /* Pointer to Screen structure (Dummy) */
  69.     NULL,        /* Pointer to custom Bitmap */
  70.     10,10,        /* Minimum Width, Height */
  71.     320,200,        /* Maximum Width, Height */
  72.     CUSTOMSCREEN
  73.      };
  74.  
  75.  
  76.  
  77. main()        /* Here we go, action kids! */
  78. {
  79.  
  80. /* open the intuition and graphics libraries.
  81.    get pointer to Writable Control Store routines (ROM for all intents),
  82.    if = 0, libraries aren't available */
  83.  
  84. IntuitionBase = (struct IntuitionBase *)
  85.     OpenLibrary("intuition.library",LIBRARY_VERSION);
  86. if (IntuitionBase == NULL) exit (FALSE);
  87.  
  88. GfxBase = (struct GfxBase *)
  89.     OpenLibrary("graphics.library",LIBRARY_VERSION);
  90. if (GfxBase == NULL) 
  91.     {
  92.      CloseLibrary(IntuitionBase);     /* end of the line, get some memory!*/
  93.      exit (FALSE);
  94.     }
  95.  
  96. /* Open screen and window .  if they return 0, it didn't work! */
  97.  
  98.  if (( NewWdw.Screen = Scr = (struct Screen *)OpenScreen(&NewScr)) == NULL)
  99.     {
  100.      CloseLibrary(GfxBase);    
  101.      CloseLibrary(IntuitionBase);    /* go home early */
  102.      exit (FALSE);
  103.     }
  104.  
  105.  if (( Wdw = (struct Window *)OpenWindow(&NewWdw)) == NULL)
  106.     {
  107.     CloseScreen(Scr);
  108.     CloseLibrary(GfxBase);        /* be nice, and clean up your room */
  109.     CloseLibrary(IntuitionBase);
  110.     exit(FALSE);  
  111.      }
  112.  
  113.  WVP = (struct ViewPort *)ViewPortAddress(Wdw);   /* Specify our View Port */
  114.  
  115.  workspace = AllocRaster(320,200);    /* Try to grab a workspace for Flood */
  116.  if (workspace == 0)
  117.  {
  118.     CloseWindow(Wdw);
  119.     CloseScreen(Scr);        /* If failure, close shop */
  120.     CloseLibrary(GfxBase);
  121.     CloseLibrary(IntuitionBase);
  122.     exit(FALSE);  
  123.  }
  124.   
  125.  InitTmpRas(&myTmpRas,workspace,RASSIZE(320,200));  /* Do this so Intuition */
  126.  Rp->TmpRas = &myTmpRas;        /* will be able to use Flood */
  127.  
  128.  LoadRGB4(WVP,&colormap,16);     /* Set up the colormap with our values */
  129.  
  130.  
  131.  SetAPen(Rp,15);         /* Draw a few concentric filled Ellipses */
  132.  DrawEllipse(Rp,230,100,60,60);
  133.  Flood(Rp,1,(short)230,(short)100);
  134.  
  135.  SetAPen(Rp,0); 
  136.  DrawEllipse(Rp,230,100,45,45);
  137.  Flood(Rp,1,(short)230,(short)100);
  138.  
  139.  SetAPen(Rp,15); 
  140.  DrawEllipse(Rp,230,100,30,30);
  141.  Flood(Rp,1,(short)230,(short)100);
  142.  
  143.  SetAPen(Rp,0); 
  144.  DrawEllipse(Rp,230,100,15,15);
  145.  Flood(Rp,1,(short)230,(short)100);
  146.  
  147.  polycolor = 15;        /* Draw some ANTIALIASED FILLED CIRCLES!! */
  148.  SetAPen(Rp,15);
  149.  aacircle(90,100,60); 
  150.  
  151.  polycolor = 0; 
  152.  SetAPen(Rp,0);
  153.  aacircle(90,100,45);
  154.  
  155.  polycolor = 15;
  156.  SetAPen(Rp,15);
  157.  aacircle(90,100,30); 
  158.  
  159.  polycolor = 0; 
  160.  SetAPen(Rp,0);
  161.  aacircle(90,100,15); 
  162.  
  163.  
  164.  for (;;)    /* wait until user closes his window */
  165.   {
  166.   
  167.    if (message = (struct IntuiMessage *)GetMsg(Wdw->UserPort))
  168.     {
  169.         MessageClass = message->Class;
  170.         code = message->Code;
  171.         ReplyMsg(message);
  172.         if (MessageClass == CLOSEWINDOW)
  173.         {
  174.         FreeRaster(workspace,320,200);
  175.                 CloseWindow(Wdw);
  176.         CloseScreen(Scr);
  177.         CloseLibrary(GfxBase);
  178.         CloseLibrary(IntuitionBase);
  179.                 return;
  180.         }
  181.     }
  182.   }
  183. }
  184.  
  185.  
  186.  
  187.  
  188.  
  189. /*  aacircle draws an antialiased, filled circle */
  190.  
  191. aacircle(xcent, ycent, rad)
  192. int xcent, ycent, rad;   /* center of circle, and radius (in pixels) */
  193. {
  194.   int x,y;       /* current x, y  position in quadrant */
  195.   int r;         /* remainder þo factor division out of the loop*/
  196.  
  197.   y = 0;       /* start on the x-axis */
  198.   x = rad;    /* with x=radius */
  199.   r = x;    /* initialize remainder for round off. */
  200.         /* the left and right edges, the top and bottom are assumed */
  201.         /* to exactly cover a whole pixel, I fill those in first */
  202.  
  203.   fill(xcent-rad,ycent,xcent+rad);    /* draw middle line in */
  204.   wdot(xcent,ycent+rad,polycolor);    /* the top dot, */
  205.   wdot(xcent,ycent-rad,polycolor);    /* and bottom dot */
  206.   while (y++ < x)    /* loop for all scan lines in 1/2 quadrant */
  207.   { 
  208.     r = r-y;    /* do next step in iterative division */
  209.     if (r<0)    /* when underflow occurs, it's time to */
  210.     {
  211.         x=x-1;    /* subtract a whole pixel from x */
  212.         r=r+x;    /* and push the remainder back up */
  213.                 /* fill in a line in the top and bottom */
  214.         fill(xcent-y+1,ycent+x,xcent+y-1);    /* sections of the */    
  215.         fill(xcent-y+1,ycent-x,xcent+y-1);    /* circle */
  216.     }
  217.  
  218.     fill(xcent-x+1,ycent+y,xcent+x-1);    /* always fill a line across */
  219.     fill(xcent-x+1,ycent-y,xcent+x-1);    /* the center of the circle */
  220.     multi = r;    /* set the globals that specify the color */
  221.     divis = x;    /* coverage ratio for this edge pixel */
  222.  
  223.     adot(xcent-x,ycent+y);    /* replicate this dot in all four quadrants */
  224.     adot(xcent+x,ycent+y);
  225.     adot(xcent-x,ycent-y);
  226.     adot(xcent+x,ycent-y);
  227.     adot(xcent-y,ycent-x);     /* and use xy symmetry to generate the upper */
  228.     adot(xcent+y,ycent-x);    /* half of each quadrant */
  229.     adot(xcent-y,ycent+x);
  230.     adot(xcent+y,ycent+x);
  231.    }
  232.    return;
  233.  
  234. }
  235.  
  236. wdot(x,y,color)        /* writes a dot of 'color' to screen */ 
  237. int x,y,color;
  238. {
  239.     SetAPen(Rp,color);
  240.     WritePixel(Rp,x,y);
  241.     return;
  242. }
  243.  
  244.  
  245. fill(x1,y1,x2)        /* fills in pixels between two points in "polycolor" */
  246. int x1,y1,x2;
  247. {
  248.    SetAPen(Rp,polycolor);
  249.    Move(Rp,x1,y1);
  250.    Draw(Rp,x2,y1);
  251.    return;
  252. }
  253.  
  254.  
  255.  
  256. adot(x,y)    /* routine to write one anti-aliased polygon edge dot */
  257. int x,y;    
  258. {
  259.     int color;    /* storage for calculated color */
  260.     int v;    /* color of pixel to be written over */
  261.     int d;    /* distance between pixel and polycolor */
  262.  
  263.     v = ReadPixel(Rp,x,y);    /* read present color of pixel */
  264.     d = v - polycolor;        /* calculate difference of pixels */
  265.     d = d*multi/divis;        /* and interpolate new distances between */
  266.                 /* these two colors */
  267.     color = (v-d);  /* calculate the new color, between two original colors*/
  268.  
  269.     wdot(x,y,color);    /* write the pixel out */
  270.     return;        /* th-th-that's all folks */
  271. }
  272.  
  273.  
  274. /* Acknowledgement to Mike Higgens, who provided this algorithm, as well as
  275.    example programs, which I liberally adapted to my own nefarious purposes */
  276.