/* Demonstration of jittering to achieve the depth-of-field effect Written by Caroline Geiersbach and Scott D. Anderson scott.anderson@acm.org Summer 2003 */ #include #include // for exit #include /* values for the camera. compute near and far based on a bounding box of (-5,5,-5,5,-5,5).*/ GLfloat fovy=90; GLfloat ar=1; GLfloat near=3.0; GLfloat far=21.0; GLfloat left=-3; GLfloat right=3; GLfloat bottom=-3; GLfloat top=3; void reshape(int width, int height) { glViewport(0,0,width,height); } /* Set up camera. Note that near, far, and focus remain fixed; all that is modified with the accumulation buffer is the eye location.*/ void accCamera(GLfloat eyedx, GLfloat eyedy, GLfloat focus) { GLfloat dx,dy; glMatrixMode(GL_PROJECTION); glLoadIdentity(); dx = (eyedx/focus)*(focus-near); dy = (eyedy/focus)*(focus-near); // printf("dx = %.5f, dy = %.5f\n", dx, dy); glFrustum(left+dx,right+dx,bottom+dy,top+dy,near,far); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); // Translating the coordinate system by (eyedx,eyedy) is the same as // moving the eye by (-eyedx,-eyedy). glTranslatef(eyedx,eyedy,0.0); } GLfloat eyeMovement(GLfloat focus, GLfloat depth, GLfloat blurUnits) { GLfloat term1 = (focus-depth-near)/(focus-depth); GLfloat term2 = (focus-near)/focus; GLfloat result = -blurUnits/(term1-term2); // printf("E = %f as a function of %f %f %f\n",result,focus,depth,blurUnits); return result; } // From the OpenGL Programming Guide, first edition, table 10-5 float jitterTable[][2] = { {0.5625, 0.4375}, {0.0625, 0.9375}, {0.3125, 0.6875}, {0.6875, 0.8124}, {0.8125, 0.1875}, {0.9375, 0.5625}, {0.4375, 0.0625}, {0.1875, 0.3125}}; void dofCamera(int jitterIndex, float focus, float depth) { GLfloat dx, dy; GLint viewport[4]; glGetIntegerv(GL_VIEWPORT, viewport); GLfloat windowWidth=viewport[2]; GLfloat windowHeight=viewport[3]; GLfloat frustumWidth=right-left; GLfloat frustumHeight=top-bottom; GLfloat cx = frustumWidth/windowWidth; GLfloat cy = frustumHeight/windowHeight; GLfloat eyedx = eyeMovement(focus,depth,(jitterTable[jitterIndex][0]-0.5)*2*cx); GLfloat eyedy = eyeMovement(focus,depth,(jitterTable[jitterIndex][1]-0.5)*2*cy); accCamera(eyedx,eyedy,focus); } /*Draw teapot at the location (x,y,z) with the color (red, green, blue) */ void drawObject(GLfloat x, GLfloat y, GLfloat z, GLfloat red, GLfloat green, GLfloat blue) { glPushMatrix(); glTranslatef(x,y,z); twTriple color = {red, green, blue}; twColor(color,0.9,128.0); glutSolidTeapot(1); glPopMatrix(); twDrawString(x-1,y-1.5,z,"(%1.0f,%1.0f,%1.0f)",x,y,z); } GLfloat DepthOfField; // a command-line argument void display(void) { int jitter; int numJitters = 8; glClear(GL_ACCUM_BUFFER_BIT); for(jitter=0; jitter