home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- /*
- * envmap -
- * Environment map a spin object in real-time.
- *
- * Paul Haeberli - 1990
- */
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <gl.h>
- #include <device.h>
- #include <vect.h>
-
- #include "ui.h"
- #include "fastobj.h"
- #include "texture.h"
- #include "envmap.h"
-
- /****************************************************************************/
-
- char *ProgName = 0;
- char StrOption[] = "DW:b:fe:t:?";
- char StrUsage[] = "[-Df] [-W x0,y0[,x1,y1] [-b ModelName] [-e EnvName] [-t TextureName]";
-
- long Xorigin, Yorigin, Xsize, Ysize;
- int UsePrefsize = 0;
- int UsePrefposition = 0;
-
- #define SHADE_INFINITE 0
- #define SHADE_LOCAL 1
-
- int debugmode = 0;
- int fullscreenmode = 0;
-
- int dotrans = 0;
- int solidtex = 0, transtex = 0;
-
- int shadehow = SHADE_INFINITE;
-
- fastobj *obj;
-
- char envname[200];
- char transenvname[200];
- char modelname[200];
-
- settrans(trans)
- int trans;
- {
- if(trans) {
- settexture(transtex);
- blendfunction(BF_ONE,BF_ONE);
- zfunction(ZF_ALWAYS);
- } else {
- settexture(solidtex);
- blendfunction(BF_ONE,BF_ZERO);
- zfunction(ZF_LEQUAL);
- }
- }
-
- clearscreen()
- {
- zclear();
- if(dotrans) {
- backface(0);
- RGBcolor(0,0,0);
- } else {
- backface(0);
- RGBcolor(0,0,0);
- }
- clear();
- }
-
- static void Usage()
- {
- fprintf(stderr, "usage: %s %s\n", ProgName, StrUsage);
- }
-
- docmdline(argc, argv)
- int argc;
- char **argv;
- {
- int opt;
- struct stat buf;
- extern char *optarg;
- extern int getopt();
-
- while ((opt = getopt(argc, argv, StrOption)) != -1) {
- switch(opt) {
- case '?':
- Usage();
- exit(1);
-
- case 'D':
- debugmode ^= 1;
- printf("debugmode=%d\n",debugmode);
- break;
-
- case 'W': /* provide x1,y1,x2,y2 or just xsize, ysize */
- if (4 == sscanf(optarg, "%d,%d,%d,%d", &Xorigin, &Yorigin,
- &Xsize, &Ysize)) {
- UsePrefposition = 1;
- } else if (2 == sscanf(optarg, "%d,%d", &Xsize, &Ysize)) {
- UsePrefsize = 1;
- } else {
- Usage();
- exit(-1);
- }
- break;
-
- case 'f':
- fullscreenmode ^= 1;
- printf("fullscreenmode=%d\n",fullscreenmode);
- break;
-
- case 't':
- if (optarg[0] == '/') {
- strcpy(transenvname, optarg);
- } else {
- if (stat(optarg, &buf) == 0) {
- strcpy(transenvname, optarg);
- } else {
- strcpy(transenvname, TEXDIR);
- strcat(transenvname, optarg);
- }
- }
- fprintf(stderr, "transparent environment map is %s\n",
- transenvname);
- transtex = 2;
- dotrans = 1;
- break;
-
- case 'b':
- if (optarg[0] == '/') {
- strcpy(modelname, optarg);
- } else {
- if (stat(optarg, &buf) == 0) {
- strcpy(modelname, optarg);
- } else {
- strcpy(modelname, MODELDIR);
- strcat(modelname, optarg);
- }
- }
- if (!(obj = readfastobj(modelname))) {
- fprintf(stderr, "envmap: can't read %s\n", modelname);
- exit(1);
- }
- break;
-
- case 'e':
- if (optarg[0] == '/') {
- strcpy(envname, optarg);
- } else {
- if (stat(optarg, &buf) == 0) {
- strcpy(envname, optarg);
- } else {
- strcpy(envname, ENVDIR);
- strcat(envname, optarg);
- }
- }
- solidtex = 1;
- transtex = 1;
- fprintf(stderr, "solid environment map is %s\n", envname);
- break;
-
- default:
- fprintf(stderr, "usage: envmap object map.env [trans.env]\n");
- exit(1);
- break;
- }
- }
- if (!obj) {
- fprintf(stderr, "envmap: no bin file given!\n");
- exit(1);
- }
- if (!solidtex) {
- fprintf(stderr, "envmap: no environment file given!\n");
- exit(1);
- }
- }
-
- #define ZTRANS (-1.6)
-
- static float s_axis[3] = { 0.5, 1.0, 0.0};
- static float spin[4] = { 0.0, 0.0, 0.0, 1.0};
- static float total_rotation[4] = { 0.0, 0.0, 0.0, 1.0};
- static float pos[3] = { 0.0, 0.0, ZTRANS};
- static int spinning = FALSE;
-
- void
- draw_object()
- {
- Matrix m;
-
- clearscreen();
-
- pushmatrix();
-
- translate(pos[0], pos[1], pos[2]);
- build_rotmatrix(m, total_rotation);
- multmatrix(m);
-
- if (dotrans) cpack(0x80808080);
- else cpack(0xFFFFFFFF);
- drawenvobj(obj, m);
-
- popmatrix();
-
- swapbuffers();
- }
-
- /*
- * Called by ui interface, passed a float[4] that is a rotation
- * specified in Euler paramaters and a float[3] that is xyz
- * translation. (no rotation is {0.0, 0.0, 0.0, 1.0}, no translation
- * is {0.0, 0.0, 0.0})
- */
- void
- remember_view(float *rot, float *trans)
- {
- vcopy(rot, spin);
- spin[3] = rot[3];
- vadd(trans, pos, pos);
-
- add_quats(spin, total_rotation, total_rotation);
-
- draw_object();
- }
-
- void
- spin_scene()
- {
- add_quats(spin, total_rotation, total_rotation);
-
- draw_object();
- }
-
- void
- redraw_scene() /* Called when aspect ratio might change */
- {
- float aspect;
- long xdim, ydim;
-
- getsize(&xdim,&ydim);
- aspect = (float) xdim/(float) ydim;
- perspective(450,aspect,0.1,100.0);
-
- draw_object();
- }
-
- void
- anything_moving(int *flag)
- {
- if (spin[0] == 0.0 && spin[1] == 0.0 && spin[2] == 0.0)
- (*flag) = FALSE;
- else (*flag) = TRUE;
- }
-
- static long menu = (-1);
-
- void
- build_menu()
- {
- if (menu != (-1)) freepup(menu);
-
- menu = newpup();
- addtopup(menu, "Environment Map %t");
- if (!dotrans)
- addtopup(menu, "Transparent Model %x1");
- else
- addtopup(menu, "Solid Model %x2");
- if (shadehow == SHADE_LOCAL)
- addtopup(menu, "Infinite Viewer %x3");
- else
- addtopup(menu, "Local Viewer %x4");
- addtopup(menu, "Reset %x5");
- addtopup(menu, "Exit %x6");
- }
- void
- do_menu()
- {
- int needredraw = 0;
-
- switch (dopup(menu))
- {
- case 1: /* Transparent model */
- dotrans = 1;
- settrans(dotrans);
- needredraw=1;
- break;
- case 2: /* Solid model */
- dotrans = 0;
- settrans(dotrans);
- needredraw=1;
- break;
- case 3: /* Infinite viewer */
- shadehow = SHADE_INFINITE;
- needredraw=1;
- break;
- case 4: /* Local viewer */
- shadehow = SHADE_LOCAL;
- needredraw=1;
- break;
- case 5: /* Reset */
- vzero(pos); pos[2] = ZTRANS;
- vzero(total_rotation);
- total_rotation[3] = 1.0;
- vzero(spin);
- spin[3] = 1.0;
- spinning = FALSE;
- shadehow = SHADE_INFINITE;
- dotrans = 0;
- needredraw=1;
- break;
- case 6:
- ui_exit();
- break;
- }
- if (needredraw)
- {
- build_menu();
- qenter(REDRAW,1);
- }
- }
-
- main(argc,argv)
- int argc;
- char **argv;
- {
- float aspect;
- long xdim, ydim;
- short val;
-
- docmdline(argc, argv);
-
- if (debugmode)
- foreground();
-
- if (UsePrefsize)
- prefsize(Xsize, Ysize);
- else if (UsePrefposition)
- prefposition(Xorigin, Xorigin + Xsize - 1,
- Yorigin, Yorigin + Ysize - 1);
- else if (fullscreenmode)
- prefposition(0, XMAXSCREEN, 0, YMAXSCREEN);
-
- /* Open with the executable's name (stripped of directory) */
- {
- char *t, *strrchr(char *, int);
- winopen((t=strrchr(argv[0], '/')) != NULL ? t+1 : argv[0]);
- }
-
- subpixel(TRUE);
- doublebuffer();
- RGBmode();
- gconfig();
-
- build_menu();
-
- textureread(envname, solidtex, 4, 0);
- if (dotrans) {
- textureread(transenvname, transtex, 4, 0);
- }
- settrans(dotrans);
-
- zbuffer(TRUE);
- mmode(MVIEWING);
-
- getsize(&xdim,&ydim);
- aspect = (float) xdim/(float) ydim;
- perspective(450,aspect,0.1,100.0);
-
- add_event(ANY, RIGHTMOUSE, DOWN, do_menu, NULL);
- qdevice(RIGHTMOUSE);
- add_event(ANY, ESCKEY, UP, ui_exit, NULL);
- qdevice(ESCKEY);
- add_event(ANY, WINQUIT, ANY, ui_exit, NULL);
- qdevice(WINQUIT);
- add_event(ANY, REDRAW, ANY, redraw_scene, NULL);
- qdevice(REDRAW);
-
- add_update(&spinning, spin_scene, NULL);
- add_event(ANY, ANY, ANY, anything_moving, (unsigned char *)&spinning);
-
- axis_to_quat(s_axis, 0.1, spin);
-
- qenter(REDRAW, 1);
- ui(remember_view);
- gexit();
- exit(0);
- }
-
- xformvect(matrix,v,tv)
- float matrix[4][4];
- float *v, *tv;
- {
- tv[0] = v[0]*matrix[0][0] + v[1]*matrix[1][0] + v[2]*matrix[2][0];
- tv[1] = v[0]*matrix[0][1] + v[1]*matrix[1][1] + v[2]*matrix[2][1];
- tv[2] = v[0]*matrix[0][2] + v[1]*matrix[1][2] + v[2]*matrix[2][2];
- }
-
- #define TMDIV 2.1
-
- tmnorm(n,p,mat)
- float *n, *p;
- float mat[4][4];
- {
- float eye[3], tn[3], tp[3], tex[3];
- float ref[3], ahead[3], half[3], c[3];
- float col[3];
-
- switch(shadehow) {
- case SHADE_INFINITE:
- xformvect(mat,n,tn);
- if(tn[2]<0.0) {
- tn[0] = -tn[0];
- tn[1] = -tn[1];
- tn[2] = -tn[2];
- }
- tex[0] = 0.5+tn[0]/TMDIV;
- tex[1] = 0.5+tn[1]/TMDIV;
- t2f(tex);
- break;
- case SHADE_LOCAL:
- xformvect(mat,n,tn);
- if(tn[2]<0.0) {
- tn[0] = -tn[0];
- tn[1] = -tn[1];
- tn[2] = -tn[2];
- }
- xformvect(mat,p,tp);
- vadd(tp, pos, tp);
- vcopy(tp, eye);
- vnormal(eye);
- vreflect(eye,tn,ref);
- ahead[0] = 0.0;
- ahead[1] = 0.0;
- ahead[2] = -1.0;
- vhalf(ref,ahead,half);
- tex[0] = 0.5-(half[0]/TMDIV);
- tex[1] = 0.5-(half[1]/TMDIV);
- t2f(tex);
- break;
- }
- }
-
- drawenvobj(obj,mat)
- fastobj *obj;
- float mat[4][4];
- {
- register float *p;
- register int npolys;
-
- npolys = obj->npoints/4;
- p = (float *)obj->data;
- while(npolys--) {
- bgnpolygon();
- tmnorm(p,p+4,mat);
- v3f(p+4);
- p += 8;
- tmnorm(p,p+4,mat);
- v3f(p+4);
- p += 8;
- tmnorm(p,p+4,mat);
- v3f(p+4);
- p += 8;
- tmnorm(p,p+4,mat);
- v3f(p+4);
- p += 8;
- endpolygon();
- }
- }
-