/* * pushmatrix * * Push the top matrix of the stack down, placing a copy * of it on the top of the stack. * */ void pushmatrix(void) { Mstack *tmpmat; Token *p; if (vdevice.inobject) { p = newtokens(1); p->i = PUSHMATRIX; return; } if (msfree != (Mstack *)NULL) { tmpmat = vdevice.transmat; vdevice.transmat = msfree; msfree = msfree->back; vdevice.transmat->back = tmpmat; copymatrix(vdevice.transmat->m, tmpmat->m); } else { tmpmat = (Mstack *)vallocate(sizeof(Mstack)); tmpmat->back = vdevice.transmat; copymatrix(tmpmat->m, vdevice.transmat->m); vdevice.transmat = tmpmat; } }
/* * popviewport * * pops the top viewport off the viewport stack. * */ void popviewport() { Token *tok; Vstack *nvport; if (!vdevice.initialised) verror("popviewport: vogle not initialised"); if (vdevice.inobject) { tok = newtokens(1); tok->i = POPVIEWPORT; return; } if (vdevice.viewport->back == (Vstack *)NULL) verror("popviewport: viewport stack underflow"); else { nvport = vdevice.viewport; vdevice.viewport = vdevice.viewport->back; nvport->back = vsfree; vsfree = nvport; } vdevice.maxVx = vdevice.viewport->v.right * vdevice.sizeX; vdevice.maxVy = vdevice.viewport->v.top * vdevice.sizeY; vdevice.minVx = vdevice.viewport->v.left * vdevice.sizeX; vdevice.minVy = vdevice.viewport->v.bottom * vdevice.sizeY; CalcW2Vcoeffs(); }
/* * rectf * * draw a filled rectangle given two opposite corners * */ void rectf(Coord x1, Coord y1, Coord x2, Coord y2) { Token *tok; if (!vdevice.initialised) verror("rect: vogl not initialised"); if (vdevice.inobject) { tok = newtokens(5); tok[0].i = RECTF; tok[1].f = x1; tok[2].f = y1; tok[3].f = x2; tok[4].f = y2; return; } pmv2(x1, y1); pdr2(x2, y1); pdr2(x2, y2); pdr2(x1, y2); pdr2(x1, y1); pclos(); }
/* * loadmatrix * * Replace the top matrix on the stack * */ void loadmatrix(float (*mat)[4]) { register int i; register float *cm, *mp; Token *p; if (!vdevice.initialised) verror("loadmatrix: vogl not initialised"); if (vdevice.inobject) { p = newtokens(17); p[0].i = LOADMATRIX; cm = (float *)mat; for (i = 0; i < 16; i++) (++p)->f = *cm++; return; } cm = (float *)vdevice.transmat->m; mp = (float *)mat; for (i = 0; i < 16; i++) *cm++ = *mp++; vdevice.cpVvalid = 0; /* may have changed mapping from world to device coords */ }
/* * popmatrix * * Pop the top matrix from the stack. * */ void popmatrix(void) { Token *p; Mstack *oldtop; if (vdevice.inobject) { p = newtokens(1); p->i = POPMATRIX; return; } if (vdevice.transmat->back == (Mstack *)NULL) verror("popmatrix: matrix stack empty"); else { oldtop = vdevice.transmat; vdevice.transmat = vdevice.transmat->back; oldtop->back = msfree; msfree = oldtop; } vdevice.cpVvalid = 0; /* may have changed mapping from world to device coords */ }
/* * rcrv * * draws a rational curve * */ void rcrv(Coord (*geom)[4]) { Matrix d, tmp; float *m, xlast, ylast, zlast; Token *tok; int i; if (!vdevice.initialised) verror("rcrv: vogl not initialised"); mult4x4(d, vdevice.tbasis, geom); /* * Find the last point on the curve.... */ xlast = d[0][0] + d[1][0] + d[2][0] + d[3][0]; ylast = d[0][1] + d[1][1] + d[2][1] + d[3][1]; zlast = d[0][2] + d[1][2] + d[2][2] + d[3][2]; /* * Mult. by the precision matrix.... */ mult4x4(tmp, e, d); if (vdevice.inobject) { tok = newtokens(21); tok[0].i = RCURVE; (++tok)->i = nsegs; (++tok)->f = xlast; (++tok)->f = ylast; (++tok)->f = zlast; m = (float *)tmp; for (i = 0; i < 16; i++) (++tok)->f = *m++; return; } /* * Multiply by the current transformation matrix. */ mult4x4(d, tmp, vdevice.transmat->m); /* * Draw the curve..... */ drcurve(nsegs, d); /* * Set the current world position to the last point (This * is the untransformed one) */ vdevice.cpW[V_X] = xlast; vdevice.cpW[V_Y] = ylast; vdevice.cpW[V_Z] = zlast; }
/* * pclos * * draw the polygon started by the above. */ void pclos(void) { float lstx, lsty, lstz; Vector result; int i, j; Token *tok; if (!vdevice.initialised) verror("pclos: vogl not initialised"); vdevice.inpolygon = 0; if (vdevice.inobject) { tok = newtokens(2 + 3 * (numv + 1)); tok[0].i = POLYF; tok[1].i = numv + 1; for (i = 0, j = 2; i <= numv; i++, j += 3) { tok[j + V_X].f = p[i][V_X]; tok[j + V_Y].f = p[i][V_Y]; tok[j + V_Z].f = p[i][V_Z]; } return; } lstx = p[numv][V_X]; lsty = p[numv][V_Y]; lstz = p[numv][V_Z]; numv++; for (i = 0; i < numv; i++) { multvector(result, p[i], vdevice.transmat->m); p[i][V_X] = result[V_X]; p[i][V_Y] = result[V_Y]; p[i][V_Z] = result[V_Z]; p[i][V_W] = result[V_W]; } dopoly(numv); vdevice.cpW[V_X] = lstx; vdevice.cpW[V_Y] = lsty; vdevice.cpW[V_Z] = lstz; }
/* * polf * * construct a filled polygon from an array of points provided * by the user. */ void polf(long int nv, float (*dp)[3]) { int i, j; Vector vect, result; Token *tok; long n = nv; if (!vdevice.initialised) verror("poly: vogl not initialised"); vdevice.fill = polymodeflag; if (vdevice.inobject) { tok = newtokens(2 + 3 * n); tok[0].i = POLYF; tok[1].i = n; for (i = 0, j = 2; i < n; i++, j += 3) { tok[j + V_X].f = dp[i][V_X]; tok[j + V_Y].f = dp[i][V_Y]; tok[j + V_Z].f = dp[i][V_Z]; } return; } for (i = 0; i < n; i++) { vect[V_X] = dp[i][V_X]; vect[V_Y] = dp[i][V_Y]; vect[V_Z] = dp[i][V_Z]; vect[V_W] = 1; multvector(result, vect, vdevice.transmat->m); p[i][V_X] = result[V_X]; p[i][V_Y] = result[V_Y]; p[i][V_Z] = result[V_Z]; p[i][V_W] = result[V_W]; } dopoly(n); vdevice.cpW[V_X] = dp[0][V_X]; vdevice.cpW[V_Y] = dp[0][V_Y]; vdevice.cpW[V_Z] = dp[0][V_Z]; vdevice.fill = 0; }
/* * multmatrix * * Premultipy the top matrix on the stack by "mat" * */ void multmatrix(float (*mat)[4]) { Matrix prod; float *m; Token *p; int i; if (vdevice.inobject) { p = newtokens(17); p[0].i = MULTMATRIX; m = (float *)mat; for (i = 0; i < 16; i++) (++p)->f = *m++; return; } mult4x4(prod, mat, vdevice.transmat->m); loadmatrix(prod); }
/* * pushviewport * * pushes the current viewport on the viewport stack * */ void pushviewport() { Vstack *nvport; Token *tok; if (!vdevice.initialised) verror("pushviewport: vogle not initialised"); if (vdevice.inobject) { tok = newtokens(1); tok->i = PUSHVIEWPORT; return; } if (vsfree != (Vstack *)NULL) { nvport = vdevice.viewport; vdevice.viewport = vsfree; vsfree = vsfree->back; vdevice.viewport->back = nvport; vdevice.viewport->v.left = nvport->v.left; vdevice.viewport->v.right = nvport->v.right; vdevice.viewport->v.bottom = nvport->v.bottom; vdevice.viewport->v.top = nvport->v.top; } else { nvport = (Vstack *)vallocate(sizeof(Vstack)); nvport->back = vdevice.viewport; nvport->v.left = vdevice.viewport->v.left; nvport->v.right = vdevice.viewport->v.right; nvport->v.bottom = vdevice.viewport->v.bottom; nvport->v.top = vdevice.viewport->v.top; vdevice.viewport = nvport; } }
/* * polymode * * Sets the polygon filling mode - only filled or outlined supported */ void polymode(long int mode) { Token *tok; if (!vdevice.initialised) verror("polymode: vogl not initialised"); if (vdevice.inobject) { tok = newtokens(2); tok[0].i = POLYMODE; tok[1].i = (int)mode; return; } /* * On older SGI Machines this call used to work... On the newer * boxes it doesn't do anything. If you want the old stuff then * #define OLD_SGI_BOXES somewhere. */ #define OLD_SGI_BOXES 1 #ifdef OLD_SGI_BOXES polymodeflag = mode; #endif }