예제 #1
0
파일: r_cin.c 프로젝트: codetwister/qfusion
/*
* 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;
}
예제 #2
0
파일: r_cin.c 프로젝트: Picmip/qfusion
/*
* 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 );
}