summaryrefslogtreecommitdiffstats
path: root/progs/ggi/asc-view.c
diff options
context:
space:
mode:
Diffstat (limited to 'progs/ggi/asc-view.c')
-rw-r--r--progs/ggi/asc-view.c353
1 files changed, 353 insertions, 0 deletions
diff --git a/progs/ggi/asc-view.c b/progs/ggi/asc-view.c
new file mode 100644
index 00000000000..16f53e55091
--- /dev/null
+++ b/progs/ggi/asc-view.c
@@ -0,0 +1,353 @@
+/*
+ test program for the ggi-mesa driver
+
+ Copyright (C) 1997,1998 Uwe Maurer - [email protected]
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <sys/time.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <GL/gl.h>
+#include <GL/ggimesa.h>
+#include <ggi/ggi.h>
+#include <stdlib.h>
+
+ggi_visual_t vis,vis_mem;
+
+GGIMesaContext ctx;
+
+int screen_x=320,screen_y=200;
+ggi_graphtype bpp=GT_16BIT;
+
+//#define ZBUFFER
+
+//#define SMOOTH_NORMALS
+
+void Init()
+{
+ GLfloat h=(GLfloat)3/4;
+ GLfloat pos[4]={5,5,-20,0};
+ GLfloat specular[4]={.4,.4,.4,1};
+ GLfloat diffuse[4]={.3,.3,.3,1};
+ GLfloat ambient[4]={.2,.2,.2,1};
+
+ int err;
+
+ if (ggiInit()<0)
+ {
+ printf("ggiInit() failed\n");
+ exit(1);
+ }
+ ctx=GGIMesaCreateContext();
+ if (ctx==NULL)
+ {
+ printf("Can't create Context!\n");
+ exit(1);
+ }
+
+ vis=ggiOpen(NULL);
+ vis_mem=ggiOpen("display-memory",NULL);
+ if (vis==NULL || vis_mem==NULL)
+ {
+ printf("Can't open ggi_visuals!\n");
+ exit(1);
+ }
+ err=ggiSetGraphMode(vis,screen_x,screen_y,screen_x,screen_y,bpp);
+ err+=ggiSetGraphMode(vis_mem,screen_x,screen_y,screen_x,screen_y,bpp);
+ if (err)
+ {
+ printf("Can't set %ix%i\n",screen_x,screen_y);
+ exit(1);
+ }
+
+ if (GGIMesaSetVisual(ctx,vis_mem,GL_TRUE,GL_FALSE)<0)
+ {
+ printf("GGIMesaSetVisual() failed!\n");
+ exit(1);
+ }
+
+ GGIMesaMakeCurrent(ctx);
+
+ glViewport(0,0,screen_x,screen_y);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustum(-1,1,-h,h,1,50);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(0,0,-9);
+ glShadeModel(GL_FLAT);
+
+ glFrontFace(GL_CW);
+ glEnable(GL_CULL_FACE);
+ glEnable(GL_LIGHTING);
+ glEnable(GL_LIGHT0);
+
+ glLightfv(GL_LIGHT0,GL_POSITION,pos);
+
+ glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuse);
+ glLightfv(GL_LIGHT0,GL_AMBIENT,ambient);
+ glLightfv(GL_LIGHT0,GL_SPECULAR,specular);
+
+ #ifdef ZBUFFER
+ glEnable(GL_DEPTH_TEST);
+ #endif
+}
+
+
+#define MAX_VERTS 1000
+#define MAX_TRIS 2000
+#define MAX_LEN 1024
+#define MAX_F 100000000
+
+void LoadAsc(GLuint *list,char *file)
+{
+ FILE *fp;
+
+ GLfloat p[MAX_VERTS][3];
+ GLfloat normal[MAX_VERTS][3];
+ float ncount[MAX_VERTS];
+ int v[MAX_TRIS][3];
+ char line[MAX_LEN];
+ char *s;
+ int i,j;
+ int verts,faces;
+ GLuint v0,v1,v2;
+ GLfloat n[3];
+ GLfloat len,k;
+ GLfloat min[3]={MAX_F,MAX_F,MAX_F};
+ GLfloat max[3]={-MAX_F,-MAX_F,-MAX_F};
+ char *coord_str[]={"X","Z","Y"};
+
+ fp=fopen(file,"r");
+ if (!fp)
+ {
+ printf("Can't open %s!\n",file);
+ exit(1);
+ }
+
+ while (strncmp(fgets(line,MAX_LEN,fp),"Tri-mesh",8)) ;
+
+ s=strstr(line,":")+1;
+ verts=atoi(s);
+ s=strstr(s,":")+1;
+ faces=atoi(s);
+
+ if (verts>MAX_VERTS)
+ {
+ printf("Too many vertices..\n");
+ exit(1);
+ }
+
+ while (strncmp(fgets(line,MAX_LEN,fp),"Vertex list",11)) ;
+
+ for (i=0;i<verts;i++)
+ {
+ while (strncmp(fgets(line,MAX_LEN,fp),"Vertex",6)) ;
+ for (j=0;j<3;j++)
+ {
+ s=strstr(line,coord_str[j])+2;
+ k=atoi(s);
+ if (k>max[j]) max[j]=k;
+ if (k<min[j]) min[j]=k;
+ p[i][j]=k;
+ }
+
+ }
+ len=0;
+ for (i=0;i<3;i++)
+ {
+ k=max[i]-min[i];
+ if (k>len) {len=k;j=i;}
+ n[i]=(max[i]+min[i])/2;
+ }
+
+ len/=2;
+
+ for (i=0;i<verts;i++)
+ {
+ for (j=0;j<3;j++)
+ {
+ p[i][j]-=n[j];
+ p[i][j]/=len;
+ }
+ }
+
+ *list=glGenLists(1);
+ glNewList(*list,GL_COMPILE);
+ glBegin(GL_TRIANGLES);
+
+ memset(ncount,0,sizeof(ncount));
+ memset(normal,0,sizeof(normal));
+
+ while (strncmp(fgets(line,MAX_LEN,fp),"Face list",9)) ;
+ for (i=0;i<faces;i++)
+ {
+ while (strncmp(fgets(line,MAX_LEN,fp),"Face",4)) ;
+ s=strstr(line,"A")+2;
+ v0=v[i][0]=atoi(s);
+ s=strstr(line,"B")+2;
+ v1=v[i][1]=atoi(s);
+ s=strstr(line,"C")+2;
+ v2=v[i][2]=atoi(s);
+ n[0]=((p[v1][1]-p[v0][1])*(p[v2][2]-p[v0][2])
+ - (p[v1][2]-p[v0][2])*(p[v2][1]-p[v0][1]));
+ n[1]=((p[v1][2]-p[v0][2])*(p[v2][0]-p[v0][0])
+ - (p[v1][0]-p[v0][0])*(p[v2][2]-p[v0][2]));
+ n[2]=((p[v1][0]-p[v0][0])*(p[v2][1]-p[v0][1])
+ - (p[v1][1]-p[v0][1])*(p[v2][0]-p[v0][0]));
+ len=n[0]*n[0]+n[1]*n[1]+n[2]*n[2];
+ len=sqrt(len);
+ n[0]/=len;
+ n[1]/=len;
+ n[2]/=len;
+ #ifdef SMOOTH_NORMALS
+ for (j=0;j<3;j++){
+ normal[v[i][j]][0]+=n[0];
+ normal[v[i][j]][1]+=n[1];
+ normal[v[i][j]][2]+=n[2];
+ ncount[v[i][j]]++;
+ }
+ #else
+ glNormal3fv(n);
+ for (j=0;j<3;j++)
+ glVertex3fv(p[v[i][j]]);
+ #endif
+ }
+
+ #ifdef SMOOTH_NORMALS
+ for (i=0;i<verts;i++) {
+ for (j=0;j<3;j++) {
+ normal[i][j]/=ncount[i];
+ }
+ }
+ for (i=0;i<faces;i++) {
+ for (j=0;j<3;j++) {
+ glNormal3f(normal[v[i][j]][0],
+ normal[v[i][j]][1],
+ normal[v[i][j]][2]);
+ glVertex3fv(p[v[i][j]]);
+ }
+ }
+ #endif
+
+ glEnd();
+ glEndList();
+ fclose(fp);
+}
+
+double Display(GLuint l,int *maxframes)
+{
+ int x,y;
+ GLfloat col[]={.25,0,.25,1};
+ int frames=0;
+ struct timeval start,stop;
+ double len;
+ GLfloat rotate=0;
+
+ gettimeofday(&start,NULL);
+
+
+ while(1)
+ {
+ glClearColor(0,0,0,0);
+ glClearIndex(0);
+
+ #ifdef ZBUFFER
+ glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
+ #else
+ glClear(GL_COLOR_BUFFER_BIT);
+ #endif
+
+ glPushMatrix();
+
+ glRotatef(30,1,0,0);
+ glRotatef(rotate/10,0,0,1);
+ glTranslatef(-6,-4,0);
+ for (y=0;y<3;y++)
+ {
+ glPushMatrix();
+ for (x=0;x<5;x++)
+ {
+ glPushMatrix();
+ glRotatef(rotate,y+1,-x-1,0);
+
+ col[0]=(GLfloat)(x+1)/4;
+ col[1]=0;
+ col[2]=(GLfloat)(y+1)/2;
+ glMaterialfv(GL_FRONT,GL_AMBIENT,col);
+ glCallList(l);
+ glPopMatrix();
+ glTranslatef(3,0,0);
+ }
+ glPopMatrix();
+ glTranslatef(0,4,0);
+ }
+ glPopMatrix();
+ glFinish();
+
+ ggiPutBox(vis,0,0,screen_x,screen_y,ggiDBGetBuffer(vis,0)->read);
+ rotate+=10;
+ frames++;
+ if (frames==(*maxframes)) break;
+
+ if (ggiKbhit(vis))
+ {
+ *maxframes=frames;
+ break;
+ }
+ }
+
+ gettimeofday(&stop,NULL);
+ len=(double)(stop.tv_sec-start.tv_sec)+
+ (double)(stop.tv_usec-start.tv_usec)/1e6;
+ return len;
+}
+
+
+int main(int argc,char **argv)
+{
+ GLuint l;
+ char *file;
+ int maxframes=0;
+ double len;
+
+ Init();
+
+ file=(argc>1) ? argv[1] : "asc/box.asc";
+ if (argc>2) maxframes=atoi(argv[2]);
+
+ if (argc==1)
+ {
+ printf("usage: %s filename.asc\n",argv[0]);
+ }
+
+ LoadAsc(&l,file);
+
+ len=Display(l,&maxframes);
+
+ printf("\ttime: %.3f sec\n",len);
+ printf("\tframes: %i\n",maxframes);
+ printf("\tfps: %.3f \n",(double)maxframes/len);
+
+ GGIMesaDestroyContext(ctx);
+ ggiClose(vis);
+ ggiClose(vis_mem);
+ ggiExit();
+ return 0;
+}
+