/* motionblur.c - by Tom McReynolds, SGI */ /* Using the accumulation buffer for motion blur. */ #include #include #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] =(float)(((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(-60.f + dx,-60.f + dy,-420.f + dz); glScalef(2.0f,2.0f,2.0f) ; glCallList(SPHERE); glPopMatrix(); glPushMatrix(); glTranslatef(20.f + dx,-80.f + dy,-600.f + dz); glScalef(2.0f,2.0f,2.0f) ; glCallList(CONE); glPopMatrix(); if( glGetError() ) printf("Oops! I screwed up my OpenGL calls somewhere\n"); glFlush(); } enum {NONE,FIELD}; int rendermode = NONE; void CALLBACK redraw(void) { 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(); auxSwapBuffers(); } const int TEXDIM = 256; void CALLBACK myReshape(int w,int h) { glViewport(0,0,w,h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-FRUSTDIM,FRUSTDIM,-FRUSTDIM,FRUSTDIM,FRUSTNEAR,FRUSTFAR); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void CALLBACK keySpace(void) { if ( rendermode == NONE ) rendermode = FIELD ; else rendermode = NONE ; redraw(); } void init(void) { 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; 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); } void main(void) { auxInitDisplayMode(AUX_DOUBLE|AUX_RGBA|AUX_DEPTH|AUX_ACCUM); auxInitPosition(0,0,300,300); auxInitWindow("Motion blur") ; init(); auxKeyFunc(AUX_SPACE,keySpace) ; auxReshapeFunc(myReshape); auxMainLoop(redraw); }