/* =============== R_SetupProjection =============== */ void R_SetupProjection(viewParms_t *dest, float zProj, qboolean computeFrustum) { float xmin, xmax, ymin, ymax; float width, height, stereoSep = r_stereoSeparation->value; float dx, dy; vec2_t pixelJitter, eyeJitter; /* * offset the view origin of the viewer for stereo rendering * by setting the projection matrix appropriately. */ if(stereoSep != 0) { if(dest->stereoFrame == STEREO_LEFT) stereoSep = zProj / stereoSep; else if(dest->stereoFrame == STEREO_RIGHT) stereoSep = zProj / -stereoSep; else stereoSep = 0; } //ri.Printf(PRINT_ALL, "zProj: %f\n", zProj); ymax = zProj * tan(dest->fovY * M_PI / 360.0f); ymin = -ymax; xmax = zProj * tan(dest->fovX * M_PI / 360.0f); xmin = -xmax; width = xmax - xmin; height = ymax - ymin; if (tr.recordingVideo || mme_dofVisualize->integer) { pixelJitter[0] = pixelJitter[1] = 0; eyeJitter[0] = eyeJitter[1] = 0; /* Jitter the view */ if (mme_dofFrames->integer > 0) { if (r_anaglyphMode->integer == 19 && *ri.SplitVideo && !tr.leftRecorded) { R_MME_JitterView( pixelJitter, eyeJitter, qfalse ); } else { R_MME_JitterView( pixelJitter, eyeJitter, qtrue ); } } dx = ( pixelJitter[0]*width ) / backEnd.viewParms.viewportWidth; dy = ( pixelJitter[1]*height ) / backEnd.viewParms.viewportHeight; dx += eyeJitter[0]; dy += eyeJitter[1]; xmin += dx; xmax += dx; ymin += dy; ymax += dy; } dest->projectionMatrix[0] = 2 * zProj / width; dest->projectionMatrix[4] = 0; dest->projectionMatrix[8] = (xmax + xmin + 2 * stereoSep) / width; dest->projectionMatrix[12] = 2 * zProj * stereoSep / width; dest->projectionMatrix[1] = 0; dest->projectionMatrix[5] = 2 * zProj / height; dest->projectionMatrix[9] = ( ymax + ymin ) / height; // normally 0 dest->projectionMatrix[13] = 0; dest->projectionMatrix[3] = 0; dest->projectionMatrix[7] = 0; dest->projectionMatrix[11] = -1; dest->projectionMatrix[15] = 0; // Now that we have all the data for the projection matrix we can also setup the view frustum. if(computeFrustum) { R_SetupFrustum(dest, xmin, xmax, ymax, zProj, stereoSep); } }
static void SetFinalProjection( void ) { float xmin, xmax, ymin, ymax; float width, height, depth; float zNear, zFar, zProj, stereoSep; float dx, dy; vec2_t pixelJitter, eyeJitter; // // set up projection matrix // zNear = r_znear->value; zFar = backEnd.viewParms.zFar; zProj = r_zproj->value; stereoSep = r_stereoSeparation->value / 100.0f; ymax = zNear * tan( backEnd.viewParms.fovY * M_PI / 360.0f ); ymin = -ymax; xmax = zNear * tan( backEnd.viewParms.fovX * M_PI / 360.0f ); xmin = -xmax; width = xmax - xmin; height = ymax - ymin; depth = zFar - zNear; pixelJitter[0] = pixelJitter[1] = 0; eyeJitter[0] = eyeJitter[1] = 0; /* Jitter the view */ if ( stereoSep <= 0.0f) { R_MME_JitterView( pixelJitter, eyeJitter ); } else if ( stereoSep > 0.0f) { R_MME_JitterViewStereo( pixelJitter, eyeJitter ); } dx = ( pixelJitter[0]*width ) / backEnd.viewParms.viewportWidth; dy = ( pixelJitter[1]*height ) / backEnd.viewParms.viewportHeight; dx += eyeJitter[0]; dy += eyeJitter[1]; xmin += dx; xmax += dx; ymin += dy; ymax += dy; qglMatrixMode(GL_PROJECTION); qglPushMatrix(); qglLoadIdentity(); qglFrustum( xmin, xmax, ymin, ymax, zNear, zFar ); qglGetFloatv(GL_PROJECTION_MATRIX, backEnd.viewParms.projectionMatrix ); qglPopMatrix(); backEnd.viewParms.projectionMatrix[0] = 2 * zNear / width; backEnd.viewParms.projectionMatrix[4] = 0; backEnd.viewParms.projectionMatrix[8] = ( xmax + xmin + 2 * stereoSep ) / width; // normally 0 backEnd.viewParms.projectionMatrix[12] = 2 * zProj * stereoSep / width; backEnd.viewParms.projectionMatrix[1] = 0; backEnd.viewParms.projectionMatrix[5] = 2 * zNear / height; backEnd.viewParms.projectionMatrix[9] = ( ymax + ymin ) / height; // normally 0 backEnd.viewParms.projectionMatrix[13] = 0; backEnd.viewParms.projectionMatrix[2] = 0; backEnd.viewParms.projectionMatrix[6] = 0; backEnd.viewParms.projectionMatrix[10] = -( zFar + zNear ) / depth; backEnd.viewParms.projectionMatrix[14] = -2 * zFar * zNear / depth; backEnd.viewParms.projectionMatrix[3] = 0; backEnd.viewParms.projectionMatrix[7] = 0; backEnd.viewParms.projectionMatrix[11] = -1; backEnd.viewParms.projectionMatrix[15] = 0; }