| /* |
| test program for the ggi-mesa driver |
| |
| Copyright (C) 1997,1998 Uwe Maurer - uwe_maurer@t-online.de |
| |
| 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=GGI_AUTO,screen_y=GGI_AUTO; |
| ggi_graphtype bpp=GT_AUTO; |
| |
| //#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; |
| } |
| |
| void visible(int vis) |
| { |
| if (vis == GLUT_VISIBLE) |
| glutIdleFunc(idle); |
| else |
| glutIdleFunc(NULL); |
| } |
| |
| int main(int argc, char *argv[]) |
| { |
| glutInit(&argc, argv); |
| glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); |
| |
| glutInitWindowPosition(0, 0); |
| glutInitWindowSize(300, 300); |
| glutCreateWindow("asc-view"); |
| init(); |
| |
| glutDisplayFunc(draw); |
| glutReshapeFunc(reshape); |
| glutKeyboardFunc(key); |
| glutSpecialFunc(special); |
| glutVisibilityFunc(visible); |
| |
| glutMainLoop(); |
| #if 0 |
| 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(); |
| #endif |
| return 0; |
| } |
| |