/* * R_ResampleCinematicFrame */ static image_t *R_ResampleCinematicFrame( r_cinhandle_t *handle ) { const int samples = 4; if( !handle->pic ) { // we haven't yet read a new frame, return whatever image we got // this will return NULL until at least one frame has been read return handle->image; } if( handle->yuv ) { int i; if( !handle->yuv_images[0] ) { qbyte *fake_data[1] = { NULL }; const char *letters[3] = { "y", "u", "v" }; for( i = 0; i < 3; i++ ) { handle->yuv_images[i] = R_LoadImage( va( "%s_%s", handle->name, letters[i] ), fake_data, 1, 1, IT_CINEMATIC|IT_LUMINANCE, 1 ); } handle->new_frame = qtrue; } if( handle->new_frame ) { int fbo; qboolean in2D; // render/convert three 8-bit YUV images into RGB framebuffer in2D = rf.in2D; fbo = RFB_BoundObject(); if( !in2D ) { R_PushRefInst(); } R_InitViewportTexture( &handle->image, handle->name, 0, handle->cyuv->image_width, handle->cyuv->image_height, 0, IT_CINEMATIC|IT_FRAMEBUFFER, samples ); R_BindFrameBufferObject( handle->image->fbo ); R_Set2DMode( qtrue ); RB_Scissor( 0, 0, handle->image->upload_width, handle->image->upload_height ); RB_Viewport( 0, 0, handle->image->upload_width, handle->image->upload_height ); // flip the image vertically because we're rendering to a FBO R_DrawStretchRawYUVBuiltin( 0, 0, handle->image->upload_width, handle->image->upload_height, (float)handle->cyuv->x_offset / handle->cyuv->image_width, (float)handle->cyuv->y_offset / handle->cyuv->image_height, (float)(handle->cyuv->x_offset + handle->cyuv->width) / handle->cyuv->image_width, (float)(handle->cyuv->y_offset + handle->cyuv->height) / handle->cyuv->image_height, handle->cyuv->yuv, handle->yuv_images, 2 ); if( !in2D ) { R_PopRefInst( 0 ); } R_BindFrameBufferObject( fbo ); R_Set2DMode( in2D ); handle->new_frame = qfalse; } } else { if( !handle->image ) { handle->image = R_LoadImage( handle->name, &handle->pic, handle->width, handle->height, IT_CINEMATIC, samples ); handle->new_frame = qfalse; } else if( handle->new_frame ) { R_ReplaceImage( handle->image, &handle->pic, handle->width, handle->height, handle->image->flags, samples ); handle->new_frame = qfalse; } } return handle->image; }
/* * R_UploadCinematicFrame */ static void R_UploadCinematicFrame( r_cinhandle_t *handle ) { const int samples = 4; ri.Mutex_Lock( handle->lock ); if( !handle->cin || !handle->pic ) { ri.Mutex_Unlock( handle->lock ); return; } if( handle->yuv ) { int i; if( !handle->yuv_images[0] ) { char tn[256]; uint8_t *fake_data[1] = { NULL }; const char *letters[3] = { "y", "u", "v" }; for( i = 0; i < 3; i++ ) { handle->yuv_images[i] = R_LoadImage( va_r( tn, sizeof( tn ), "%s_%s", handle->name, letters[i] ), fake_data, 1, 1, IT_SPECIAL | IT_NO_DATA_SYNC, 1, IMAGE_TAG_GENERIC, 1 ); } handle->new_frame = true; } if( handle->new_frame ) { bool multiSamples2D; bool in2D; // render/convert three 8-bit YUV images into RGB framebuffer in2D = rf.twoD.enabled; multiSamples2D = rf.twoD.multiSamples; if( in2D ) { R_End2D(); } else { R_PushRefInst(); } R_InitViewportTexture( &handle->image, handle->name, 0, handle->cyuv->image_width, handle->cyuv->image_height, 0, IT_SPECIAL | IT_FRAMEBUFFER, IMAGE_TAG_GENERIC, samples ); R_BindFrameBufferObject( handle->image->fbo ); R_SetupGL2D(); RB_Scissor( 0, 0, handle->image->upload_width, handle->image->upload_height ); RB_Viewport( 0, 0, handle->image->upload_width, handle->image->upload_height ); R_UploadRawYUVPic( handle->yuv_images, handle->cyuv->yuv ); // flip the image vertically because we're rendering to a FBO R_DrawStretchRawYUVBuiltin( 0, 0, handle->image->upload_width, handle->image->upload_height, (float)handle->cyuv->x_offset / handle->cyuv->image_width, (float)handle->cyuv->y_offset / handle->cyuv->image_height, (float)( handle->cyuv->x_offset + handle->cyuv->width ) / handle->cyuv->image_width, (float)( handle->cyuv->y_offset + handle->cyuv->height ) / handle->cyuv->image_height, handle->yuv_images, 2 ); if( in2D ) { R_Begin2D( multiSamples2D ); } else { R_PopRefInst(); } handle->new_frame = false; } } else { if( !handle->image ) { handle->image = R_LoadImage( handle->name, (uint8_t **)&handle->pic, handle->width, handle->height, IT_SPECIAL | IT_NO_DATA_SYNC, 1, IMAGE_TAG_GENERIC, samples ); } if( handle->new_frame ) { R_ReplaceImage( handle->image, (uint8_t **)&handle->pic, handle->width, handle->height, handle->image->flags, 1, samples ); handle->new_frame = false; } } ri.Mutex_Unlock( handle->lock ); }