/* motionblur.c - by Tom McReynolds, SGI */ /* Using the accumulation buffer for motion blur. */ #include #include #include #include const GLdouble FRUSTDIM = 100.F; const GLdouble FRUSTNEAR = 320.F; const GLdouble FRUSTFAR = 660.F; GLfloat *make_texture(int maxs,int maxt) { int s,t; static GLfloat *texture; texture =(GLfloat *)malloc(maxs * maxt * sizeof(GLfloat)); for(t = 0; t < maxt; t++) { for(s = 0; s < maxs; s++) { texture[s + maxs * t] =((s >> 4) & 0x1) ^((t >> 4) & 0x1); } } return texture; } enum {SPHERE = 1,CONE}; void render(GLfloat dx,GLfloat dy,GLfloat dz) { static GLfloat wall_mat[] = {1.F,1.F,1.F,1.F}; glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT); glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,wall_mat); glEnable(GL_TEXTURE_2D); glBegin(GL_QUADS); glNormal3f(0.F,1.F,0.F); glTexCoord2i(0,0); glVertex3f(-100.F,-100.F,-320.F); glTexCoord2i(1,0); glVertex3f(100.F,-100.F,-320.F); glTexCoord2i(1,1); glVertex3f(100.F,-100.F,-640.F); glTexCoord2i(0,1); glVertex3f(-100.F,-100.F,-640.F); glEnd(); glDisable(GL_TEXTURE_2D); glBegin(GL_QUADS); glNormal3f(1.F,0.F,0.F); glVertex3f(-100.F,-100.F,-320.F); glVertex3f(-100.F,-100.F,-640.F); glVertex3f(-100.F,100.F,-640.F); glVertex3f(-100.F,100.F,-320.F); glNormal3f(-1.F,0.F,0.F); glVertex3f(100.F,-100.F,-320.F); glVertex3f(100.F,100.F,-320.F); glVertex3f(100.F,100.F,-640.F); glVertex3f(100.F,-100.F,-640.F); glNormal3f(0.F,-1.F,0.F); glVertex3f(-100.F,100.F,-320.F); glVertex3f(-100.F,100.F,-640.F); glVertex3f(100.F,100.F,-640.F); glVertex3f(100.F,100.F,-320.F); glNormal3f(0.F,0.F,1.F); glVertex3f(-100.F,-100.F,-640.F); glVertex3f(100.F,-100.F,-640.F); glVertex3f(100.F,100.F,-640.F); glVertex3f(-100.F,100.F,-640.F); glEnd(); glPushMatrix(); glTranslatef(-80.F + dx,-60.F + dy,-420.F + dz); glCallList(SPHERE); glPopMatrix(); glPushMatrix(); glTranslatef(-20.F,-80.F,-600.F); glCallList(CONE); glPopMatrix(); if( glGetError() ) printf("Oops! I screwed up my OpenGL calls somewhere\n"); glFlush(); } enum {NONE,FIELD}; int rendermode = NONE; void menu(int selection) { rendermode = selection; glutPostRedisplay(); } GLdouble focus = 420.; void redraw() { int i; int max; GLfloat dx,dy,dz; dx = .5f; dy = 1.F; dz = -2.F; glPushMatrix(); switch(rendermode) { case NONE : render(0.F,0.F,0.F); break; case FIELD : max = 16; glClear(GL_ACCUM_BUFFER_BIT); for ( i = 0 ; i < max ; i++ ) { render(dx * i,dy * i,dz * i); glAccum(GL_ACCUM,1.F/max); } glAccum(GL_RETURN,1.F); break; } glPopMatrix(); glutSwapBuffers(); } void key(unsigned char key,int x,int y) { if(key == '\033') exit(0); } const int TEXDIM = 256; int main(int argc,char **argv) { glutInit(&argc,argv); GLfloat *tex; static GLfloat lightpos[] = {50.F,50.F,-320.F,1.F}; static GLfloat sphere_mat[] = {1.F,.5f,0.F,1.F}; static GLfloat cone_mat[] = {0.F,.5f,1.F,1.F}; GLUquadricObj *sphere,*cone,*base; glutInitWindowSize(300,300); glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_ACCUM|GLUT_DOUBLE); glutCreateWindow("Motion blur"); glutDisplayFunc(redraw); glutKeyboardFunc(key); glutCreateMenu(menu); glutAddMenuEntry("Normal",NONE); glutAddMenuEntry("Motion Blur",FIELD); glutAttachMenu(GLUT_RIGHT_BUTTON); glMatrixMode(GL_PROJECTION); glFrustum(-FRUSTDIM,FRUSTDIM,-FRUSTDIM,FRUSTDIM,FRUSTNEAR,FRUSTFAR); glMatrixMode(GL_MODELVIEW); glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glLightfv(GL_LIGHT0,GL_POSITION,lightpos); glCullFace(GL_BACK); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); glNewList(SPHERE,GL_COMPILE); sphere = gluNewQuadric(); glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,sphere_mat); gluSphere(sphere,20.F,20,20); gluDeleteQuadric(sphere); glEndList(); glNewList(CONE,GL_COMPILE); cone = gluNewQuadric(); base = gluNewQuadric(); glRotatef(-90.F,1.F,0.F,0.F); glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,cone_mat); gluDisk(base,0.,20.,20,1); gluCylinder(cone,20.,0.,60.,20,20); gluDeleteQuadric(cone); gluDeleteQuadric(base); glEndList(); tex = make_texture(TEXDIM,TEXDIM); glTexImage2D(GL_TEXTURE_2D,0,1,TEXDIM,TEXDIM,0,GL_RED,GL_FLOAT,tex); free(tex); glutMainLoop(); return(0); }