378 lines
7.2 KiB
C
378 lines
7.2 KiB
C
|
/*
|
||
|
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;
|
||
|
}
|
||
|
|