示例#1
0
/*
* R_RenderScene
*/
void R_RenderScene( const refdef_t *fd )
{
	int fbFlags = 0;
	int ppFrontBuffer = 0;
	image_t *ppSource;

	if( r_norefresh->integer )
		return;

	R_Set2DMode( false );

	RB_SetTime( fd->time );

	if( !( fd->rdflags & RDF_NOWORLDMODEL ) )
		rsc.refdef = *fd;

	rn.refdef = *fd;
	if( !rn.refdef.minLight ) {
		rn.refdef.minLight = 0.1f;
	}

	fd = &rn.refdef;

	rn.renderFlags = RF_NONE;

	rn.farClip = R_DefaultFarClip();
	rn.clipFlags = 15;
	if( rsh.worldModel && !( fd->rdflags & RDF_NOWORLDMODEL ) && rsh.worldBrushModel->globalfog )
		rn.clipFlags |= 16;
	rn.meshlist = &r_worldlist;
	rn.portalmasklist = &r_portalmasklist;
	rn.shadowBits = 0;
	rn.dlightBits = 0;
	rn.shadowGroup = NULL;

	fbFlags = 0;
	rn.fbColorAttachment = rn.fbDepthAttachment = NULL;
	
	if( !( fd->rdflags & RDF_NOWORLDMODEL ) ) {
		if( r_soft_particles->integer && ( rsh.screenTexture != NULL ) ) {
			rn.fbColorAttachment = rsh.screenTexture;
			rn.fbDepthAttachment = rsh.screenDepthTexture;
			rn.renderFlags |= RF_SOFT_PARTICLES;
			fbFlags |= 1;
		}

		if( rsh.screenPPCopies[0] && rsh.screenPPCopies[1] ) {
			int oldFlags = fbFlags;
			shader_t *cc = rn.refdef.colorCorrection;

			if( r_fxaa->integer ) {
				fbFlags |= 2;
			}

			if( cc && cc->numpasses > 0 && cc->passes[0].images[0] && cc->passes[0].images[0] != rsh.noTexture ) {
				fbFlags |= 4;
			}

			if( fbFlags != oldFlags ) {
				if( !rn.fbColorAttachment ) {
					rn.fbColorAttachment = rsh.screenPPCopies[0];
					ppFrontBuffer = 1;
				}
			}
		}
	}

	ppSource = rn.fbColorAttachment;

	// clip new scissor region to the one currently set
	Vector4Set( rn.scissor, fd->scissor_x, fd->scissor_y, fd->scissor_width, fd->scissor_height );
	Vector4Set( rn.viewport, fd->x, fd->y, fd->width, fd->height );
	VectorCopy( fd->vieworg, rn.pvsOrigin );
	VectorCopy( fd->vieworg, rn.lodOrigin );

	R_BindFrameBufferObject( 0 );

	R_BuildShadowGroups();

	R_RenderView( fd );

	R_RenderDebugSurface( fd );

	R_RenderDebugBounds();

	R_BindFrameBufferObject( 0 );

	R_Set2DMode( true );

	if( !( fd->rdflags & RDF_NOWORLDMODEL ) ) {
		ri.Mutex_Lock( rf.speedsMsgLock );
		R_WriteSpeedsMessage( rf.speedsMsg, sizeof( rf.speedsMsg ) );
		ri.Mutex_Unlock( rf.speedsMsgLock );
	}

	// blit and blend framebuffers in proper order

	if( fbFlags == 1 ) {
		// only blit soft particles directly when we don't have any other post processing
		// otherwise use the soft particles FBO as the base texture on the next layer
		// to avoid wasting time on resolves and the fragment shader to blit to a temp texture
		R_BlitTextureToScrFbo( fd,
			ppSource, 0,
			GLSL_PROGRAM_TYPE_NONE,
			colorWhite, 0,
			0, NULL );
	}
	fbFlags &= ~1;

	// apply FXAA
	if( fbFlags & 2 ) {
		image_t *dest;

		fbFlags &= ~2;
		dest = fbFlags ? rsh.screenPPCopies[ppFrontBuffer] : NULL;

		R_BlitTextureToScrFbo( fd,
			ppSource, dest ? dest->fbo : 0,
			GLSL_PROGRAM_TYPE_FXAA,
			colorWhite, 0,
			0, NULL );

		ppFrontBuffer ^= 1;
		ppSource = dest;
	}

	// apply color correction
	if( fbFlags & 4 ) {
		image_t *dest;

		fbFlags &= ~4;
		dest = fbFlags ? rsh.screenPPCopies[ppFrontBuffer] : NULL;

		R_BlitTextureToScrFbo( fd,
			ppSource, dest ? dest->fbo : 0,
			GLSL_PROGRAM_TYPE_COLORCORRECTION,
			colorWhite, 0,
			1, &( rn.refdef.colorCorrection->passes[0].images[0] ) );
	}
}
示例#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 );
}
示例#3
0
/*
* 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;
}
示例#4
0
/*
* R_RenderScene
*/
void R_RenderScene( const refdef_t *fd )
{
	int fbFlags = 0;

	if( r_norefresh->integer )
		return;

	R_Set2DMode( qfalse );

	RB_SetTime( fd->time );

	if( !( fd->rdflags & RDF_NOWORLDMODEL ) )
		rsc.refdef = *fd;

	rn.refdef = *fd;
	if( !rn.refdef.minLight ) {
		rn.refdef.minLight = 0.1f;
	}
	if( !rsh.screenWeaponTexture || rn.refdef.weaponAlpha == 1 ) {
		rn.refdef.rdflags &= ~RDF_WEAPONALPHA;
	}

	fd = &rn.refdef;

	rn.renderFlags = RF_NONE;

	rn.farClip = R_DefaultFarClip();
	rn.clipFlags = 15;
	if( rsh.worldModel && !( fd->rdflags & RDF_NOWORLDMODEL ) && rsh.worldBrushModel->globalfog )
		rn.clipFlags |= 16;
	rn.meshlist = &r_worldlist;
	rn.shadowBits = 0;
	rn.dlightBits = 0;
	rn.shadowGroup = NULL;

	fbFlags = 0;
	rn.fbColorAttachment = rn.fbDepthAttachment = NULL;
	
	if( !( fd->rdflags & RDF_NOWORLDMODEL ) ) {
		// soft particles require GL_EXT_framebuffer_blit as we need to copy the depth buffer
		// attachment into a texture we're going to read from in GLSL shader
		if( r_soft_particles->integer && glConfig.ext.framebuffer_blit && ( rsh.screenTexture != NULL ) ) {
			rn.fbColorAttachment = rsh.screenTexture;
			rn.fbDepthAttachment = rsh.screenDepthTexture;
			rn.renderFlags |= RF_SOFT_PARTICLES;
			fbFlags |= 1;
		}
		if( ( fd->rdflags & RDF_WEAPONALPHA ) && ( rsh.screenWeaponTexture != NULL ) ) {
			fbFlags |= 2;
		}
		if( r_fxaa->integer && ( rsh.screenFxaaCopy != NULL ) ) {
			if( !rn.fbColorAttachment ) {
				rn.fbColorAttachment = rsh.screenFxaaCopy;
			}
			fbFlags |= 4;
		}
	}

	// adjust field of view for widescreen
	if( glConfig.wideScreen && !( fd->rdflags & RDF_NOFOVADJUSTMENT ) )
		AdjustFov( &rn.refdef.fov_x, &rn.refdef.fov_y, glConfig.width, glConfig.height, qfalse );

	// clip new scissor region to the one currently set
	Vector4Set( rn.scissor, fd->scissor_x, fd->scissor_y, fd->scissor_width, fd->scissor_height );
	Vector4Set( rn.viewport, fd->x, fd->y, fd->width, fd->height );
	VectorCopy( fd->vieworg, rn.pvsOrigin );
	VectorCopy( fd->vieworg, rn.lodOrigin );

	if( gl_finish->integer && !( fd->rdflags & RDF_NOWORLDMODEL ) )
		qglFinish();

	if( fbFlags & 2 ) {
		// clear the framebuffer we're going to render the weapon model to
		// set the alpha to 0, visible parts of the model will overwrite that,
		// creating proper alpha mask
		R_BindFrameBufferObject( rsh.screenWeaponTexture->fbo );
		RB_Clear( GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT, 0, 0, 0, 0 );
	}

	R_BindFrameBufferObject( 0 );

	R_BuildShadowGroups();

	R_RenderView( fd );

	R_RenderDebugSurface( fd );

	R_RenderDebugBounds();

	R_BindFrameBufferObject( 0 );

	R_Set2DMode( qtrue );

	// blit and blend framebuffers in proper order

	if( fbFlags & 1 ) {
		// copy to FXAA or default framebuffer
		R_BlitTextureToScrFbo( fd, rn.fbColorAttachment, 
			fbFlags & 4 ? rsh.screenFxaaCopy->fbo : 0, 
			GLSL_PROGRAM_TYPE_NONE, 
			colorWhite, 0 );
	}

	if( fbFlags & 2 ) {
		vec4_t color = { 1, 1, 1, 1 };
		color[3] = fd->weaponAlpha;

		// blend to FXAA or default framebuffer
		R_BlitTextureToScrFbo( fd, rsh.screenWeaponTexture, 
			fbFlags & 4 ? rsh.screenFxaaCopy->fbo : 0, 
			GLSL_PROGRAM_TYPE_NONE, 
			color, GLSTATE_SRCBLEND_SRC_ALPHA|GLSTATE_DSTBLEND_ONE_MINUS_SRC_ALPHA );
	}

	// blit FXAA to default framebuffer
	if( fbFlags & 4 ) {
		// blend to FXAA or default framebuffer
		R_BlitTextureToScrFbo( fd, rsh.screenFxaaCopy, 0, 
			GLSL_PROGRAM_TYPE_FXAA, 
			colorWhite, 0 );
	}
}