Path: utzoo!attcan!uunet!mcsun!hp4nl!ruuinf!markov From: markov@ruuinf.cs.ruu.nl (dr.m.h. overmars) Newsgroups: comp.sys.sgi Subject: Graphical Demo Program Keywords: Moving Objects Message-ID: <3660@ruuinf.cs.ruu.nl> Date: 2 Aug 90 13:46:55 GMT Organization: Utrecht University, Dept. of CS Lines: 736 Here follows a little demo program I wrote. Simply save it to a file, unshar it (type sh ) and type make. I hope you like it. It probably only runs well on machines that have at least Turbo Graphics. It was written and tested on a 4D/25TG. Feel free to extend it and send changes to me. Mark Overmars -------------------------------- cut here ------------------------------- #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh 'Makefile' <<'END_OF_FILE' XFILEo = moving.o object.o X XFILElib = -lgl_s -lm X Xall : moving X Xmoving : $(FILEo) X cc $(FILEo) $(FILElib) -o moving X X$(FILEo): X cc -O -c $*.c X Xclean: X rm *.o END_OF_FILE if test 168 -ne `wc -c <'Makefile'`; then echo shar: \"'Makefile'\" unpacked with wrong size! fi # end of 'Makefile' fi if test -f 'README' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'README'\" else echo shar: Extracting \"'README'\" \(1547 characters\) sed "s/^X//" >'README' <<'END_OF_FILE' Xversion 1.0 X MOVING X ====== X XThis is a simple program, showing some of the 3-dim possibilities of Xthe Graphical Library. It uses object.c that provides a number of basic Xobjects, like spheres, cubes and cylinders that can also be used in other Xprograms. moving has some special features like a moving icon, a possible Xsecond window on the same moving stuff, it can indicate the number of frames Xper second it makes, etc. X XThe right mouse button operates a menu. This has the following items: X XShow Front View: Gives you a second window. XObjects: Here you can indicate which objects you want to see. XDisplay Mode: Allows you to switch between wire frame and X filled polygons. XLighting Mode: Allows you to switch between flat shading and X Gouraud shading. XExtras: Gives you a submenu: X Backface Culling: Toggles backface culling. X Show Frames: Indicates frames per second. X Faster: Faster motion. X Slower: Slower motion. XExit: This will be clear (also exits). X XMotion can be stopped and continued at any moment by pressing the left Xmouse button. X XTo create the program, simply type make. X XThe program has only been tested on a 4D/25 TG. I think it needs at least XTG to run reasonably smooth. X XThis program and its code can be used freely. No responsibility is taken Xwhatsoever. If you make any changes (e.g. add objects), please send me Xa copy. X Xwritten by Mark Overmars, Dept. of Computer Science, Utrecht University, XEmail: markov@cs.ruu.nl. X END_OF_FILE if test 1547 -ne `wc -c <'README'`; then echo shar: \"'README'\" unpacked with wrong size! fi # end of 'README' fi if test -f 'moving.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'moving.c'\" else echo shar: Extracting \"'moving.c'\" \(10214 characters\) sed "s/^X//" >'moving.c' <<'END_OF_FILE' X#include X#include X#include X#include X#include "object.h" X X/**** X This is a simple application to use the objects defined in\ X object.c. It draws some rotating objects, using X different materials and different transformations. X It allows for multiple views of the object in different windows. X The right mouse button operates the pop-up menu. X X To add objects: X - create a new object in object.c (and object.h) X - add a draw command in redraw X - add a material and bind it X - add a menu entry X Up to 20 different objects are supported X X This is version 1.0. X X Written by Mark Overmars, Dept. of Computer Science, University of Utrecht, X Email: markov@cs.ruu.nl X****/ X X#define MAXOBJ 20 X Xint frames,back,wire,flat,incr; /* toggles to indicate whay of display */ Xint ob[MAXOBJ]; /* indicates which objects to show */ Xint lcount; /* last frame cout */ Xfloat time; /* the "time" so far */ Xfloat speed; /* the rotation speed */ Xlong win1, win2; /* the window identifiers */ X Xdrw(obj,r1,r2,r3,t1,t2,t3,s1,s2,s3,mat) X/* draws a particular object. */ XOBJECT obj; Xfloat r1,r2,r3,t1,t2,t3,s1,s2,s3; Xint mat; X{ X pushmatrix(); X rot(time*r1,'X'); rot(time*r2,'Y'); rot(time*r3,'Z'); X translate(t1,t2,t3); scale(s1,s2,s3); X lmbind(MATERIAL,mat); drawobject(obj,wire,flat); X popmatrix(); X} X Xredraw() X/* draws all the objects in the current window */ X{ X char str[100]; X backface(back); X /* clear the screen */ X zclear(); X RGBcolor(43,169,255); X clear(); X /* do the drawing */ X if (ob[0]) drw( sphere, 3.0,3.1,2.0, 2.2, 1.2, 2.0, 0.8,0.8,0.8, 1); X if (ob[1]) drw( cylinder, 3.2,2.6,1.8, -1.9, 1.2, 1.6, 0.3,0.3,1.0, 4); X if (ob[2]) drw( cube, 2.2,3.3,1.4, -1.0, 1.2,-1.5, 0.6,0.6,0.6, 3); X if (ob[3]) drw( cone, 4.2,2.1,3.2, 1.2, 1.3, 1.0, 0.5,0.5,0.8, 2); X if (ob[3]) drw( sphere, 4.2,2.1,3.2, 1.2, 1.3, 0.0, 0.5,0.5,0.5,51); X if (ob[4]) drw( sphere, 1.2,3.3,2.4, -2.0, 1.4,-2.1, 0.8,0.8,0.2, 5); X if (ob[5]) drw( cube, 3.2,3.6,2.4, 1.1, 1.6, 2.5, 0.8,0.3,0.1, 6); X if (ob[6]) drw( glass, 2.7,1.9,3.1, 1.6, 1.3, 0.7, 2.0,2.0,2.0, 7); X if (ob[7]) drw( pyramid, 2.3,2.7,3.3, 1.1, 2.3, 1.7, 0.6,0.6,0.5, 8); X /* show frame count if required */ X if (frames && winget() == win1) X { X cpack(0xffffff); X cmov(-2.1,-2.1,4.0); X sprintf(str,"%d frames per second",lcount); X charstr(str); X }; X /* ready */ X swapbuffers(); X} X X/* The identity matrix. */ XMatrix idmat = {1.0,0.0,0.0,0.0, X 0.0,1.0,0.0,0.0, X 0.0,0.0,1.0,0.0, X 0.0,0.0,0.0,1.0}; X X/* The different materials. */ Xfloat mater1[] = X {SPECULAR,0.8,0.0,0.0,DIFFUSE,0.4,0.0,0.0,SHININESS,40.0,LMNULL}; Xfloat mater51[] = X {SPECULAR,0.2,0.0,0.1,DIFFUSE,0.8,0.0,0.3,SHININESS,10.0,LMNULL}; Xfloat mater2[] = X {SPECULAR,1.0,0.4,0.0,DIFFUSE,1.0,0.4,0.0,SHININESS,80.0,LMNULL}; Xfloat mater3[] = X {SPECULAR,0.0,0.0,0.6,DIFFUSE,0.0,0.0,0.8,SHININESS,60.0,LMNULL}; Xfloat mater4[] = X {SPECULAR,0.0,1.0,0.0,DIFFUSE,0.0,0.6,0.0,SHININESS,120.0,LMNULL}; Xfloat mater5[] = X {SPECULAR,1.0,1.0,0.0,DIFFUSE,0.6,0.6,0.0,SHININESS,100.0,LMNULL}; Xfloat mater6[] = X {SPECULAR,1.0,0.0,1.0,DIFFUSE,0.6,0.0,0.6,SHININESS,120.0,LMNULL}; Xfloat mater7[] = X {SPECULAR,0.9,0.9,0.9,DIFFUSE,0.6,0.6,0.6,SHININESS,120.0,LMNULL}; Xfloat mater8[] = X {SPECULAR,0.4,0.7,0.4,DIFFUSE,0.5,1.0,0.5,SHININESS,50.0,LMNULL}; X X/* The lightsources. */ Xfloat light1[] = {LCOLOR,1.0,1.0,1.0,POSITION,10.0,10.0,5.0,0.0,LMNULL}; Xfloat light2[] = {LCOLOR,1.0,1.0,1.0,POSITION,-10.0,10.0,5.0,0.0,LMNULL}; X X/* The lightmodel. */ Xfloat model[] = {AMBIENT,0.4,0.4,0.4,LMNULL}; X Xinit() X/* Initializes all settings for a window. */ X{ X zbuffer(TRUE); X doublebuffer(); X RGBmode(); X gconfig(); X mmode(MVIEWING); X perspective(400,1.0,1.0,34.0); X loadmatrix(idmat); X /* set up the devices */ X qdevice(MOUSE1); X qdevice(MOUSE3); X qdevice(ESCKEY); X qdevice(WINFREEZE); X qdevice(WINTHAW); X /* define materials and lights */ X lmdef(DEFMATERIAL, 1, 11, mater1); X lmdef(DEFMATERIAL,51, 11, mater51); X lmdef(DEFMATERIAL, 2, 11, mater2); X lmdef(DEFMATERIAL, 3, 11, mater3); X lmdef(DEFMATERIAL, 4, 11, mater4); X lmdef(DEFMATERIAL, 5, 11, mater5); X lmdef(DEFMATERIAL, 6, 11, mater6); X lmdef(DEFMATERIAL, 7, 11, mater7); X lmdef(DEFMATERIAL, 8, 11, mater8); X lmdef(DEFLIGHT, 1, 10, light1); X lmdef(DEFLIGHT, 2, 10, light2); X lmdef(DEFLMODEL, 1, 5, model); X lmbind(LIGHT0,1); X lmbind(LIGHT1,2); X lmbind(LMODEL,1); X} X X/*** Handling the menu. ***/ X Xlong mainmenu, confirmmenu, speedmenu, formmenu, lightmenu, extramenu, omenu; X Xcreateobjectmenu() X{ X omenu = newpup(); X addtopup(omenu," Show All %x71 | Show None %x72 %l"); X if (ob[0]) {addtopup(omenu,"-> Sphere %x41");} X else {addtopup(omenu," Sphere %x41");}; X if (ob[1]) {addtopup(omenu,"-> Cylinder %x42");} X else {addtopup(omenu," Cylinder %x42");}; X if (ob[2]) {addtopup(omenu,"-> Cube %x43");} X else {addtopup(omenu," Cube %x43");}; X if (ob[3]) {addtopup(omenu,"-> Ice Cream %x44");} X else {addtopup(omenu," Ice Cream %x44");}; X if (ob[4]) {addtopup(omenu,"-> Disk %x45");} X else {addtopup(omenu," Disk %x45");}; X if (ob[5]) {addtopup(omenu,"-> Diamond %x46");} X else {addtopup(omenu," Diamond %x46");}; X if (ob[6]) {addtopup(omenu,"-> Glass %x47");} X else {addtopup(omenu," Glass %x47");}; X if (ob[7]) {addtopup(omenu,"-> Pyramid %x48");} X else {addtopup(omenu," Pyramid %x48");}; X} X Xcreateformmenu() X{ X formmenu = newpup(); X if (wire) {addtopup(formmenu,"-> Wire Frame %x11");} X else {addtopup(formmenu," Wire Frame %x11");}; X if (wire) {addtopup(formmenu," Filled %x12");} X else {addtopup(formmenu,"-> Filled %x12");}; X} X Xcreatelightmenu() X{ X lightmenu = newpup(); X if (flat) {addtopup(lightmenu,"-> Flat Shaded %x21");} X else {addtopup(lightmenu," Flat Shaded %x21");}; X if (flat) {addtopup(lightmenu," Gouraud Shaded %x22");} X else {addtopup(lightmenu,"-> Gouraud Shaded %x22");}; X} X Xcreateextramenu() X{ X extramenu = newpup(); X if (back) {addtopup(extramenu,"-> Backface Culling %x31");} X else {addtopup(extramenu," Backface Culling %x31");}; X if (frames){addtopup(extramenu,"-> Show Frames %x32 %l");} X else {addtopup(extramenu," Show Frames %x32 %l");}; X addtopup(extramenu," Faster %x33 | Slower %x34"); X} X Xcreatemenu() X/* Creates the menu */ X{ X createobjectmenu(); X createformmenu(); X createlightmenu(); X createextramenu(); X mainmenu = newpup(); X addtopup(mainmenu,"Objects Demo %t"); X if (win2 == 0){addtopup(mainmenu,"Show Front View %x1 %l");} X addtopup(mainmenu,"Objects %m",omenu); X addtopup(mainmenu,"Display Mode %m",formmenu); X addtopup(mainmenu,"Lighting Mode %m",lightmenu); X addtopup(mainmenu,"Extras %m %l",extramenu); X addtopup(mainmenu,"Exit %x5"); X confirmmenu = newpup(); X addtopup(confirmmenu,"Are You Sure? %t|Yes|No"); X} X Xdestroymenu() X/* kills all the menus */ X{ X freepup(mainmenu); X freepup(lightmenu); X freepup(formmenu); X freepup(confirmmenu); X freepup(omenu); X freepup(extramenu); X} X X Xpostmenu() X/* Displays the menu and takes action. */ X{ X long entry; X int i; X entry = dopup(mainmenu); X switch (entry) X { X case 1: setpup(mainmenu,1,PUP_GREY); X prefposition(600,1000,500,900); X win2 = winopen("Front View"); X winconstraints(); X iconsize(85,66); keepaspect(1,1); X winconstraints(); X init(); X lookat(10.0,0.0,0.0,0.0,0.0,0.0,0.0); X break; X case 5: if (dopup(confirmmenu) == 1) exit(0); X break; X case 11: wire = 1; break; X case 12: wire = 0; break; X case 21: flat = 1; break; X case 22: flat = 0; break; X case 31: back = 1 - back; break; X case 32: frames = 1 - frames; break; X case 33: speed = speed * 1.5; break; X case 34: speed = speed / 1.5; break; X case 41: X case 42: X case 43: X case 44: X case 45: X case 46: X case 47: X case 48: X case 49: X case 50: X case 51: X case 52: X case 53: X case 54: X case 55: X case 56: X case 57: X case 58: X case 59: X case 60: ob[entry-41] = 1 - ob[entry-41]; break; X case 71: for (i=0; i'object.c' <<'END_OF_FILE' X#include X#include X#include X#include "object.h" X/* X This library contains a number of basic objects plus a routine to X draw them. All objects have their center at point (0,0,0) and are X maximal in a box of size 2*2*2 around the origin. The currently X supported objects are: X X cube : a simple cube, origin is the center. X sphere : a nice looking sphere, origin is the center. X cylinder : a cylinder. X cone : a cone X glass : a nice glass X pyramid : guess what X X X X The following routines exist for use: X X makeobjects() X should be called once before using the objects. X X drawobject(obj,wire,flat) X to draw object obj. wire indicate whether wire frame X drawing is required. flat indicate whether flat shading X should be used. X X*/ X X/************************* X Making Spin Objects X*************************/ X X#define PI 3.14159265 X#define ZERO 0.00001 X Xmakespinobject(obj,smooth,rot,n,x1,z1,nx1,nz1,x2,z2,nx2,nz2) X/* makes a spin object */ XOBJECT *obj; /* the object to be created */ Xint smooth; /* whether smooth or not */ Xint rot; /* the number of rotation steps */ Xint n; /* the number of segments to spin */ Xfloat x1[],z1[]; /* (x,z) coordinates of first endpoint of segments */ Xfloat nx1[],nz1[]; /* their normals */ Xfloat x2[],z2[]; /* (x,z) coordinates of second endpoint of segments */ Xfloat nx2[],nz2[]; /* their normals */ X{ X float th,dth,a1,a2; X PATCH *p; X int i,j; X obj->numb = rot*n; X p = obj->pat = (PATCH *) malloc(obj->numb * sizeof(PATCH)); X dth = 2.0*PI/rot; X for (i=0; inumb=3;} else {p->numb = 4;}; X p->v[0].x = x1[i]*sin(th); p->n[0].x = nx1[i]*sin(a1); X p->v[0].y = x1[i]*cos(th); p->n[0].y = nx1[i]*cos(a1); X p->v[0].z = z1[i]; p->n[0].z = nz1[i]; X p->v[1].x = x1[i]*sin(th+dth); p->n[1].x = nx1[i]*sin(a2); X p->v[1].y = x1[i]*cos(th+dth); p->n[1].y = nx1[i]*cos(a2); X p->v[1].z = z1[i]; p->n[1].z = nz1[i]; X p->v[2].x = x2[i]*sin(th+dth); p->n[2].x = nx2[i]*sin(a2); X p->v[2].y = x2[i]*cos(th+dth); p->n[2].y = nx2[i]*cos(a2); X p->v[2].z = z2[i]; p->n[2].z = nz2[i]; X p->v[3].x = x2[i]*sin(th); p->n[3].x = nx2[i]*sin(a1); X p->v[3].y = x2[i]*cos(th); p->n[3].y = nx2[i]*cos(a1); X p->v[3].z = z2[i]; p->n[3].z = nz2[i]; X if (x1[i] v[1] = p->v[2]; p->n[1] = p->n[2]; X p->v[2] = p->v[3]; p->n[2] = p->n[3]; X }; X p++; X } X } X} X Xmakesmoothspinobject(obj,rot,n,x,z) X/* makes a smooth, connected spin object */ XOBJECT *obj; /* the object to be created */ Xint rot; /* the number of rotation steps */ Xint n; /* the number of points */ Xfloat x[],z[]; /* (x,z) coordinates of endpoints of segments */ X{ X float x1[20],z1[20],nx1[20],nz1[20],x2[20],z2[20],nx2[20],nz2[20],l[20]; X int i; X /* fill in the points */ X x1[0] = x[0]; z1[0] = z[0]; X for (i=1; inumb; j++) X { n3f(&p->n[j]); v3f(&p->v[j]);}; X if (wire) {endclosedline();} else {endpolygon();}; X p++; X } X} X END_OF_FILE if test 7718 -ne `wc -c <'object.c'`; then echo shar: \"'object.c'\" unpacked with wrong size! fi # end of 'object.c' fi if test -f 'object.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'object.h'\" else echo shar: Extracting \"'object.h'\" \(327 characters\) sed "s/^X//" >'object.h' <<'END_OF_FILE' Xtypedef struct { X Coord x,y,z; X} POINT; X Xtypedef struct { X int numb; /* number of vertices */ X POINT v[4]; /* vertices */ X POINT n[4]; /* normals */ X} PATCH; X Xtypedef struct { X int numb; /* number of patches */ X PATCH *pat; /* the patches */ X} OBJECT; X X XOBJECT sphere,cube,cylinder,cone,glass,pyramid; END_OF_FILE if test 327 -ne `wc -c <'object.h'`; then echo shar: \"'object.h'\" unpacked with wrong size! fi # end of 'object.h' fi echo shar: End of shell archive. exit 0