int R_MME_MultiPassNext( ) { mmeBlurControl_t* control = &passData.control; byte* outAlloc; __m64 *outAlign; int index; if ( !shotData.take || tr.finishStereo ) { shotData.take = qfalse; return 0; } if ( !control->totalFrames ) return 0; index = control->totalIndex; outAlloc = (byte *)ri.Hunk_AllocateTempMemory( mainData.pixelCount * 3 + 16); outAlign = (__m64 *)((((intptr_t)(outAlloc)) + 15) & ~15); GLimp_EndFrame(); R_MME_GetShot( outAlign ); R_MME_BlurAccumAdd( &passData.dof, outAlign ); tr.capturingDofOrStereo = qtrue; ri.Hunk_FreeTempMemory( outAlloc ); if ( ++(control->totalIndex) < control->totalFrames ) { int nextIndex = control->totalIndex; if ( ++(nextIndex) >= control->totalFrames && r_stereoSeparation->value == 0.0f ) tr.latestDofOrStereoFrame = qtrue; return 1; } control->totalIndex = 0; R_MME_BlurAccumShift( &passData.dof ); return 0; }
int R_MME_MultiPassNext (qboolean useMain) { mmeBlurControl_t *control; shotData_t *shotData; passData_t *passData; byte* outAlloc; __m64 *outAlign; //int i; if (useMain) { control = &passDataMain.control; shotData = &shotDataMain; passData = &passDataMain; } else { control = &passDataLeft.control; shotData = &shotDataLeft; passData = &passDataLeft; } if ( !control->totalFrames ) return 0; if (shotData->allocFailed) { return 0; } outAlloc = ri.Hunk_AllocateTempMemory( shotData->pixelCount * 3 + 16); outAlign = (__m64 *)((((int)(outAlloc)) + 15) & ~15); // don't call GLimp_EndFrame() //qglReadPixels(0, 0, glConfig.vidWidth, glConfig.vidHeight, GL_BGR, GL_UNSIGNED_BYTE, outAlign); qglReadPixels(0, 0, glConfig.vidWidth, glConfig.vidHeight, GL_RGB, GL_UNSIGNED_BYTE, outAlign); // testing #if 0 for (i = 0; i < glConfig.vidWidth * glConfig.vidHeight * 3; i++) { ((byte *)outAlign)[i] += i; } #endif R_MME_BlurAccumAdd( &passData->dof, outAlign ); ri.Hunk_FreeTempMemory( outAlloc ); if ( ++(control->totalIndex) < control->totalFrames ) { int nextIndex = control->totalIndex; if ( ++(nextIndex) >= control->totalFrames ) { // pass } return 1; } control->totalIndex = 0; R_MME_BlurAccumShift( &passData->dof ); return 0; }
qboolean R_MME_TakeShot( void ) { int pixelCount; byte inSound[MME_SAMPLERATE] = {0}; int sizeSound = 0; qboolean audio = qfalse, audioTaken = qfalse; qboolean doGamma; mmeBlurControl_t* blurControl = &blurData.control; if ( !shotData.take || allocFailed || tr.finishStereo ) return qfalse; shotData.take = qfalse; pixelCount = glConfig.vidHeight * glConfig.vidWidth; doGamma = (qboolean)(( mme_screenShotGamma->integer || (tr.overbrightBits > 0) ) && (glConfig.deviceSupportsGamma )); R_MME_CheckCvars(); //Special early version using the framebuffer if ( mme_saveShot->integer && blurControl->totalFrames > 0 && R_FrameBuffer_Blur( blurControl->Float[ blurControl->totalIndex ], blurControl->totalIndex, blurControl->totalFrames ) ) { byte *shotBuf; float fps; if ( ++(blurControl->totalIndex) < blurControl->totalFrames ) return qtrue; blurControl->totalIndex = 0; shotBuf = (byte *)ri.Hunk_AllocateTempMemory( pixelCount * 3 ); R_MME_MultiShot( shotBuf ); if ( doGamma ) R_GammaCorrect( shotBuf, pixelCount * 3 ); fps = shotData.fps / ( blurControl->totalFrames ); audio = ri.S_MMEAviImport(inSound, &sizeSound); R_MME_SaveShot( &shotData.main, glConfig.vidWidth, glConfig.vidHeight, fps, shotBuf, audio, sizeSound, inSound ); ri.Hunk_FreeTempMemory( shotBuf ); return qtrue; } /* Test if we need to do blurred shots */ if ( blurControl->totalFrames > 0 ) { mmeBlurBlock_t *blurShot = &blurData.shot; mmeBlurBlock_t *blurDepth = &blurData.depth; // mmeBlurBlock_t *blurStencil = &blurData.stencil; /* Test if we blur with overlapping frames */ if ( blurControl->overlapFrames ) { /* First frame in a sequence, fill the buffer with the last frames */ if (blurControl->totalIndex == 0) { int i; for ( i = 0; i < blurControl->overlapFrames; i++ ) { if ( mme_saveShot->integer ) { R_MME_BlurOverlapAdd( blurShot, i ); } if ( mme_saveDepth->integer ) { R_MME_BlurOverlapAdd( blurDepth, i ); } // if ( mme_saveStencil->integer ) { // R_MME_BlurOverlapAdd( blurStencil, i ); // } blurControl->totalIndex++; } } if ( mme_saveShot->integer == 1 ) { byte* shotBuf = R_MME_BlurOverlapBuf( blurShot ); R_MME_MultiShot( shotBuf ); if ( doGamma && mme_blurGamma->integer ) { R_GammaCorrect( shotBuf, glConfig.vidWidth * glConfig.vidHeight * 3 ); } R_MME_BlurOverlapAdd( blurShot, 0 ); } if ( mme_saveDepth->integer == 1 ) { R_MME_GetDepth( R_MME_BlurOverlapBuf( blurDepth ) ); R_MME_BlurOverlapAdd( blurDepth, 0 ); } // if ( mme_saveStencil->integer == 1 ) { // R_MME_GetStencil( R_MME_BlurOverlapBuf( blurStencil ) ); // R_MME_BlurOverlapAdd( blurStencil, 0 ); // } blurControl->overlapIndex++; blurControl->totalIndex++; } else { byte *outAlloc; __m64 *outAlign; outAlloc = (byte *)ri.Hunk_AllocateTempMemory( pixelCount * 3 + 16); outAlign = (__m64 *)((((intptr_t)(outAlloc)) + 15) & ~15); if ( mme_saveShot->integer == 1 ) { R_MME_MultiShot( (byte*)outAlign ); if ( doGamma && mme_blurGamma->integer ) { R_GammaCorrect( (byte *) outAlign, pixelCount * 3 ); } R_MME_BlurAccumAdd( blurShot, outAlign ); } if ( mme_saveDepth->integer == 1 ) { R_MME_GetDepth( (byte *)outAlign ); R_MME_BlurAccumAdd( blurDepth, outAlign ); } // if ( mme_saveStencil->integer == 1 ) { // R_MME_GetStencil( (byte *)outAlign ); // R_MME_BlurAccumAdd( blurStencil, outAlign ); // } ri.Hunk_FreeTempMemory( outAlloc ); blurControl->totalIndex++; } if ( blurControl->totalIndex >= blurControl->totalFrames ) { float fps; blurControl->totalIndex = 0; fps = shotData.fps / ( blurControl->totalFrames ); if ( mme_saveShot->integer == 1 ) { R_MME_BlurAccumShift( blurShot ); if (doGamma && !mme_blurGamma->integer) R_GammaCorrect( (byte *)blurShot->accum, pixelCount * 3); } if ( mme_saveDepth->integer == 1 ) R_MME_BlurAccumShift( blurDepth ); // if ( mme_saveStencil->integer == 1 ) // R_MME_BlurAccumShift( blurStencil ); audio = ri.S_MMEAviImport(inSound, &sizeSound); audioTaken = qtrue; // Big test for an rgba shot if ( mme_saveShot->integer == 1 && shotData.main.type == mmeShotTypeRGBA ) { int i; byte *alphaShot = (byte *)ri.Hunk_AllocateTempMemory( pixelCount * 4); byte *rgbData = (byte *)(blurShot->accum ); if ( mme_saveDepth->integer == 1 ) { byte *depthData = (byte *)( blurDepth->accum ); for ( i = 0;i < pixelCount; i++ ) { alphaShot[i*4+0] = rgbData[i*3+0]; alphaShot[i*4+1] = rgbData[i*3+1]; alphaShot[i*4+2] = rgbData[i*3+2]; alphaShot[i*4+3] = depthData[i]; } /* } else if ( mme_saveStencil->integer == 1) { byte *stencilData = (byte *)( blurStencil->accum ); for ( i = 0;i < pixelCount; i++ ) { alphaShot[i*4+0] = rgbData[i*3+0]; alphaShot[i*4+1] = rgbData[i*3+1]; alphaShot[i*4+2] = rgbData[i*3+2]; alphaShot[i*4+3] = stencilData[i]; } */ } R_MME_SaveShot( &shotData.main, glConfig.vidWidth, glConfig.vidHeight, fps, alphaShot, audio, sizeSound, inSound ); ri.Hunk_FreeTempMemory( alphaShot ); } else { if ( mme_saveShot->integer == 1 ) R_MME_SaveShot( &shotData.main, glConfig.vidWidth, glConfig.vidHeight, fps, (byte *)( blurShot->accum ), audio, sizeSound, inSound ); if ( mme_saveDepth->integer == 1 ) R_MME_SaveShot( &shotData.depth, glConfig.vidWidth, glConfig.vidHeight, fps, (byte *)( blurDepth->accum ), audio, sizeSound, inSound ); // if ( mme_saveStencil->integer == 1 ) // R_MME_SaveShot( &shotData.stencil, glConfig.vidWidth, glConfig.vidHeight, fps, (byte *)( blurStencil->accum), audio, sizeSound, inSound ); } } } if ( mme_saveShot->integer > 1 || (!blurControl->totalFrames && mme_saveShot->integer )) { byte *shotBuf = (byte *)ri.Hunk_AllocateTempMemory( pixelCount * 5 ); R_MME_MultiShot( shotBuf ); if ( doGamma ) R_GammaCorrect( shotBuf, pixelCount * 3 ); if ( shotData.main.type == mmeShotTypeRGBA ) { int i; byte *alphaBuf = shotBuf + pixelCount * 4; if ( mme_saveDepth->integer > 1 || (!blurControl->totalFrames && mme_saveDepth->integer )) { R_MME_GetDepth( alphaBuf ); // } else if ( mme_saveStencil->integer > 1 || (!blurControl->totalFrames && mme_saveStencil->integer )) { // R_MME_GetStencil( alphaBuf ); } for ( i = pixelCount - 1 ; i >= 0; i-- ) { shotBuf[i * 4 + 0] = shotBuf[i*3 + 0]; shotBuf[i * 4 + 1] = shotBuf[i*3 + 1]; shotBuf[i * 4 + 2] = shotBuf[i*3 + 2]; shotBuf[i * 4 + 3] = alphaBuf[i]; } } if (!audioTaken) audio = ri.S_MMEAviImport(inSound, &sizeSound); audioTaken = qtrue; R_MME_SaveShot( &shotData.main, glConfig.vidWidth, glConfig.vidHeight, shotData.fps, shotBuf, audio, sizeSound, inSound ); ri.Hunk_FreeTempMemory( shotBuf ); } if ( shotData.main.type == mmeShotTypeRGB ) { /* if ( mme_saveStencil->integer > 1 || ( !blurControl->totalFrames && mme_saveStencil->integer) ) { byte *stencilShot = (byte *)ri.Hunk_AllocateTempMemory( pixelCount * 1); R_MME_GetStencil( stencilShot ); if (!audioTaken && ((mme_saveStencil->integer > 1 && mme_saveShot->integer > 1) || (mme_saveStencil->integer == 1 && mme_saveShot->integer == 1))) audio = ri.S_MMEAviImport(inSound, &sizeSound); R_MME_SaveShot( &shotData.stencil, glConfig.vidWidth, glConfig.vidHeight, shotData.fps, stencilShot, audio, sizeSound, inSound ); ri.Hunk_FreeTempMemory( stencilShot ); } */ if ( mme_saveDepth->integer > 1 || ( !blurControl->totalFrames && mme_saveDepth->integer) ) { byte *depthShot = (byte *)ri.Hunk_AllocateTempMemory( pixelCount * 1); R_MME_GetDepth( depthShot ); if (!audioTaken && ((mme_saveDepth->integer > 1 && mme_saveShot->integer > 1) || (mme_saveDepth->integer == 1 && mme_saveShot->integer == 1))) audio = ri.S_MMEAviImport(inSound, &sizeSound); R_MME_SaveShot( &shotData.depth, glConfig.vidWidth, glConfig.vidHeight, shotData.fps, depthShot, audio, sizeSound, inSound ); ri.Hunk_FreeTempMemory( depthShot ); } } return qtrue; }