home *** CD-ROM | disk | FTP | other *** search
/ gondwana.ecr.mu.oz.au/pub/ / Graphics.tar / Graphics / voglw.zip / objects.c < prev    next >
C/C++ Source or Header  |  1997-02-13  |  9KB  |  473 lines

  1. #include <stdio.h>
  2.  
  3. #include "vogl.h"
  4.  
  5. extern void        polyobj();
  6.  
  7. typedef struct o {
  8.     int        obno;
  9.     TokList        *tlist;
  10.     struct o    *next;
  11. } VObject;
  12.  
  13. static VObject        *object_table[MAXENTS];
  14.  
  15. static long        obno = -1, omax = 0;
  16.  
  17. /*
  18.  * makeobj
  19.  *
  20.  *    start a new object.
  21.  *
  22.  */
  23. void
  24. makeobj(ob)
  25.     long    ob;
  26. {
  27.     VObject    *o;
  28.     int    n = ob;
  29.  
  30.     if (!vdevice.initialised)
  31.         verror("makeobj: vogl not initialised");
  32.  
  33.     for (o = object_table[n % MAXENTS]; o != (VObject *)NULL; o = o->next)
  34.         if (o->obno == n) {
  35.             delobj((long)n);
  36.             break;
  37.         }
  38.  
  39.     obno = n;
  40.     vdevice.tokens = (TokList *)NULL;
  41.  
  42.     vdevice.inobject = 1;
  43.  
  44.     if (omax <= n)
  45.         omax = n + 1;
  46. }
  47.  
  48. /*
  49.  * closeobj
  50.  *
  51.  *    close an object
  52.  */
  53. void
  54. closeobj()
  55. {
  56.     VObject    *o;
  57.  
  58.     if (!vdevice.inobject)
  59.         verror("closeobj: not in an object");
  60.  
  61.     vdevice.inobject = 0;
  62.  
  63.     o = (VObject *)vallocate(sizeof(VObject));
  64.     o->obno = obno;
  65.     o->tlist = vdevice.tokens;
  66.     o->next = object_table[obno % MAXENTS];
  67.  
  68.     object_table[obno % MAXENTS] = o;
  69.  
  70.     obno = -1;
  71. }
  72.  
  73. /*
  74.  * delobj
  75.  *
  76.  *    deletes an object, freeing its memory
  77.  */
  78. void
  79. delobj(ob)
  80.     long    ob;
  81. {
  82.     VObject    *o, *lo;
  83.     TokList    *tl, *ntl;
  84.     int    n = ob;
  85.  
  86.     for (lo = o = object_table[n % MAXENTS]; o != (VObject *)NULL; lo = o, o = o->next)
  87.         if (o->obno == n)
  88.             break;
  89.  
  90.     if (o != (VObject *)NULL) {
  91.         for (tl = o->tlist; tl != (TokList *)NULL; tl = ntl) {
  92.             ntl = tl->next;
  93.             if (tl->toks)
  94.                 free(tl->toks);
  95.  
  96.             free(tl);
  97.         }
  98.         if (lo == object_table[n % MAXENTS])
  99.             object_table[n % MAXENTS] = (VObject *)NULL;
  100.         else
  101.             lo->next = o->next;
  102.         free(o);
  103.     }
  104. }
  105.  
  106. /*
  107.  * genobj
  108.  *
  109.  *    generates a unique object identifier
  110.  */
  111. long
  112. genobj()
  113. {
  114.     return((long)omax++);
  115. }
  116.  
  117. /*
  118.  * getopenobj
  119.  *
  120.  *    returns the object currently being edited, -1 if none.
  121.  */
  122. long
  123. getopenobj()
  124. {
  125.     return((long)obno);
  126. }
  127.  
  128. /*
  129.  * doarc
  130.  *
  131.  *    draw an arc or circle.
  132.  */
  133. static void
  134. doarc(x, y, xoff, yoff, cosine, sine, nsegs)
  135.     float    x, y, xoff, yoff, cosine, sine;
  136.     int    nsegs;
  137. {
  138.     float    cx, cy, dx, dy;
  139.     int    i;
  140.  
  141.     cx = x + xoff;
  142.     cy = y + yoff;
  143.     move2(cx, cy);
  144.  
  145.     for (i = 0; i < nsegs; i++)  {
  146.         dx = cx - x;
  147.         dy = cy - y;
  148.         cx = x + dx * cosine - dy * sine;
  149.         cy = y + dx * sine + dy * cosine;
  150.         draw2(cx, cy);
  151.     }
  152. }
  153.  
  154. /*
  155.  * doarcf
  156.  *
  157.  *    draw a filled arc or circle.
  158.  */
  159. static void
  160. doarcf(x, y, xoff, yoff, cosine, sine, nsegs)
  161.     float    x, y, xoff, yoff, cosine, sine;
  162.     int    nsegs;
  163. {
  164.     float    cx, cy, dx, dy;
  165.     int    i;
  166.  
  167.     cx = x + xoff;
  168.     cy = y + yoff;
  169.     pmv2(cx, cy);
  170.  
  171.     for (i = 0; i < nsegs; i++)  {
  172.         dx = cx - x;
  173.         dy = cy - y;
  174.         cx = x + dx * cosine - dy * sine;
  175.         cy = y + dx * sine + dy * cosine;
  176.         pdr2(cx, cy);
  177.     }
  178.  
  179.     pclos();
  180. }
  181.  
  182. /*
  183.  * callobj
  184.  *
  185.  *    draws an object
  186.  */
  187. void
  188. callobj(ob)
  189.     long    ob;
  190. {
  191.     int    n = ob;
  192.     char    buf[BUFSIZ];
  193.  
  194.     VObject        *o;
  195.     TokList        *tl;
  196.     Matrix        prod, tmpmat;
  197.     Tensor        S;
  198.     int        sync, i, j;
  199.     float        cx, cy, cz, *m;
  200.     register Token    *t, *et, *pt;
  201.  
  202.     if (!vdevice.initialised)
  203.         verror("callobj: vogl not initialised");
  204.  
  205.     if (vdevice.inobject) {
  206.         t = newtokens(2);
  207.  
  208.         t[0].i = CALLOBJ;
  209.         t[1].i = n;
  210.  
  211.         return;
  212.     }
  213.  
  214.     for (o = object_table[n % MAXENTS]; o != (VObject *)NULL; o = o->next)
  215.         if (o->obno == n)
  216.             break;
  217.  
  218.     if (o == (VObject *)NULL)
  219.         return;
  220.  
  221.     if (sync = vdevice.sync)
  222.         vdevice.sync = 0;
  223.  
  224.     for (tl = o->tlist; tl != (TokList *)NULL; tl = tl->next) {
  225.         t = tl->toks;
  226.         et = &tl->toks[tl->count];
  227.         while (t != et) {
  228.             switch (t->i) {
  229.             case ARC:
  230.                 doarc(t[1].f, t[2].f, t[3].f, t[4].f, t[5].f, t[6].f, t[7].i);
  231.                 t += 8;
  232.                 break;
  233.             case ARCF:
  234.                 doarcf(t[1].f, t[2].f, t[3].f, t[4].f, t[5].f, t[6].f, t[7].i);
  235.                 t += 8;
  236.                 break;
  237.             case BACKBUFFER:
  238.                 backbuffer(t[1].i);
  239.                 t += 2;
  240.                 break;
  241.             case FRONTBUFFER:
  242.                 frontbuffer(t[1].i);
  243.                 t += 2;
  244.                 break;
  245.             case SWAPBUFFERS:
  246.                 swapbuffers();
  247.                 t += 1;
  248.                 break;
  249.             case BACKFACING:
  250.                 backface(t[1].i);
  251.                 t += 2;
  252.                 break;
  253.             case CALLOBJ:
  254.                 callobj(t[1].i);
  255.                 t += 2;
  256.                 break;
  257.             case CIRCLE:
  258.                 doarc(t[1].f, t[2].f, t[3].f, 0.0, t[4].f, t[5].f, t[6].i);
  259.                 draw2(t[1].f + t[3].f, t[2].f);
  260.                 t += 7;
  261.                 break;
  262.             case CIRCF:
  263.                 doarcf(t[1].f, t[2].f, t[3].f, 0.0, t[4].f, t[5].f, t[6].i);
  264.                 t += 7;
  265.                 break;
  266.             case RECTF:
  267.                 pmv2(t[1].f, t[2].f);
  268.                 pdr2(t[3].f, t[2].f);
  269.                 pdr2(t[3].f, t[4].f);
  270.                 pdr2(t[1].f, t[4].f);
  271.                 pdr2(t[1].f, t[2].f);
  272.                 pclos();
  273.                 t += 5;
  274.                 break;
  275.             case CLEAR:
  276.                 (*vdevice.dev.Vclear)();
  277.                 t++;
  278.                 break;
  279.             case COLOR:
  280.                 color(t[1].i);
  281.                 t += 2;
  282.                 break;
  283.             case DRAW:
  284.                 draw(t[1].f, t[2].f, t[3].f);
  285.                 t += 4;
  286.                 break;
  287.             case DRAWSTR:
  288.                 charstr(&t[1]);
  289.                 t += 2 + strlen((char *)&t[1]) / sizeof(Token);
  290.                 break;
  291.             case VFONT:
  292.                 font(t[1].i);
  293.                 t += 2;
  294.                 break;
  295.             case LOADMATRIX:
  296.                 m = (float *)vdevice.transmat->m;
  297.                 for (i = 0; i < 16; i++)
  298.                     *m++ = (++t)->f;
  299.  
  300.                 vdevice.cpVvalid = 0;           /* may have changed mapping from world to device coords */
  301.                 t++;
  302.  
  303.                 break;
  304.             case MAPCOLOR:
  305.                 mapcolor(t[1].i, t[2].i, t[3].i, t[4].i);
  306.                 t += 5;
  307.                 break;
  308.             case MOVE:
  309.                 move(t[1].f, t[2].f, t[3].f);
  310.                 t += 4;
  311.                 break;
  312.             case MULTMATRIX:
  313.                 m = (float *)tmpmat;
  314.                 for (i = 0; i < 16; i++)
  315.                     *m++ = (++t)->f;
  316.  
  317.                 mult4x4(prod, tmpmat, vdevice.transmat->m);
  318.                 loadmatrix(prod);
  319.                 t++;
  320.                 break;
  321.             case POLY:
  322.                 polyobj(t[1].i, &t[2], 0);
  323.                 t += 2 + 3 * t[1].i;
  324.                 break;
  325.             case POLYF:
  326.                 polyobj(t[1].i, &t[2], 1);
  327.                 t += 2 + 3 * t[1].i;
  328.                 break;
  329.             case CMOV:
  330.                 cmov(t[1].f, t[2].f, t[3].f);
  331.                 t += 4;
  332.                 break;
  333.             case POPATTRIBUTES:
  334.                 popattributes();
  335.                 t++;
  336.                 break;
  337.             case POPMATRIX:
  338.                 popmatrix();
  339.                 t++;
  340.                 break;
  341.             case POPVIEWPORT:
  342.                 popviewport();
  343.                 t++;
  344.                 break;
  345.             case PUSHATTRIBUTES:
  346.                 pushattributes();
  347.                 t++;
  348.                 break;
  349.             case PUSHMATRIX:
  350.                 pushmatrix();
  351.                 t++;
  352.                 break;
  353.             case PUSHVIEWPORT:
  354.                 pushviewport();
  355.                 t++;
  356.                 break;
  357.             case POLYMODE:
  358.                 polymode(t[1].i);
  359.                 t += 2;
  360.                 break;
  361.             case RCURVE:
  362.                 i = (++t)->i;
  363.                 cx = (++t)->f;
  364.                 cy = (++t)->f;
  365.                 cz = (++t)->f;
  366.                 m = (float *)tmpmat;
  367.                 for (j = 0; j < 16; j++)
  368.                     *m++ = (++t)->f;
  369.                 mult4x4(prod, tmpmat, vdevice.transmat->m);
  370.                 drcurve(i, prod);
  371.                 vdevice.cpW[V_X] = cx;
  372.                 vdevice.cpW[V_Y] = cy;
  373.                 vdevice.cpW[V_Z] = cz;
  374.                 t++;
  375.                 break;
  376.             case RPATCH:
  377.                 pt = t + 10;
  378.                 cx = (++t)->f;
  379.                 cy = (++t)->f;
  380.                 cz = (++t)->f;
  381.                 for (i = 0; i < 4; i++)
  382.                     for (j = 0; j < 4; j++) {
  383.                         S[0][i][j] = (pt++)->f;
  384.                         S[1][i][j] = (pt++)->f;
  385.                         S[2][i][j] = (pt++)->f;
  386.                         S[3][i][j] = (pt++)->f;
  387.                     }
  388.  
  389.                 transformtensor(S, vdevice.transmat->m);
  390.                 drpatch(S, t[1].i, t[2].i, t[3].i, t[4].i, t[5].i, t[6].i);
  391.  
  392.                 vdevice.cpW[V_X] = cx;
  393.                 vdevice.cpW[V_Y] = cy;
  394.                 vdevice.cpW[V_Z] = cz;
  395.                 t = pt;
  396.                 break;
  397.             case VIEWPORT:
  398.                 viewport(t[1].i, t[2].i, t[3].i, t[4].i);
  399.                 t += 5;
  400.                 break;
  401.             case LINESTYLE:
  402.                 setlinestyle((Linestyle)t[1].i);
  403.                 t += 2;
  404.                 break;
  405.             case LINEWIDTH:
  406.                 linewidth((short)t[1].i);
  407.                 t += 2;
  408.                 break;
  409.             case TRANSLATE:
  410.                 translate(t[1].f, t[2].f, t[3].f);
  411.                 t += 4;
  412.                 break;
  413.             case SCALE:
  414.                 /*
  415.                  * Do the operations directly on the top matrix of
  416.                  * the stack to speed things up.
  417.                  */
  418.  
  419.                 vdevice.transmat->m[0][0] *= t[1].f;
  420.                 vdevice.transmat->m[0][1] *= t[1].f;
  421.                 vdevice.transmat->m[0][2] *= t[1].f;
  422.                 vdevice.transmat->m[0][3] *= t[1].f;
  423.  
  424.                 vdevice.transmat->m[1][0] *= t[2].f;
  425.                 vdevice.transmat->m[1][1] *= t[2].f;
  426.                 vdevice.transmat->m[1][2] *= t[2].f;
  427.                 vdevice.transmat->m[1][3] *= t[2].f;
  428.  
  429.                 vdevice.transmat->m[2][0] *= t[3].f;
  430.                 vdevice.transmat->m[2][1] *= t[3].f;
  431.                 vdevice.transmat->m[2][2] *= t[3].f;
  432.                 vdevice.transmat->m[2][3] *= t[3].f;
  433.  
  434.                 t += 4;
  435.                 break;
  436.             case ROTATE:
  437.                 rot(t[1].f, (char)t[2].i);
  438.                 t += 3;
  439.                 break;
  440.             default:
  441.                 sprintf(buf, "vogl: internal error in callobj (Token type %d used)", t->i);
  442.                 verror(buf);
  443.                 exit(1);
  444.             }
  445.         }
  446.     }
  447.  
  448.     if (sync) {
  449.         vdevice.sync = 1;
  450.         (*vdevice.dev.Vsync)();
  451.     }
  452. }
  453.  
  454. /*
  455.  * isobj
  456.  *
  457.  *    returns 1 if there is an object n, 0 otherwise.
  458.  */
  459. Boolean
  460. isobj(ob)
  461.     long    ob;
  462. {
  463.     long    n = ob;
  464.  
  465.     VObject    *o;
  466.  
  467.     for (o = object_table[n % MAXENTS]; o != (VObject *)NULL; o = o->next)
  468.         if (o->obno == n)
  469.             break;
  470.  
  471.     return(o != (VObject *)NULL);
  472. }
  473.