示例#1
0
bool CUIMpTradeWnd::OnKeyboard(int dik, EUIMessages keyboard_action)
{
#ifdef DEBUG
	//for debug only
	if(keyboard_action==WINDOW_KEY_PRESSED && dik==DIK_NUMPAD7)
	{
		if(GetRank()>0)
			SetRank( clampr(u32(GetRank()-1),u32(0),u32(4) ) );
	}
	if(keyboard_action==WINDOW_KEY_PRESSED && dik==DIK_NUMPAD8)
	{
		SetRank( clampr(u32(GetRank()+1),u32(0),u32(4) ) );
	}
#endif

	if(!m_store_hierarchy->CurrentIsRoot())
	{
		if (m_shop_wnd->OnKeyboard(dik, keyboard_action) )
			return true;

		m_root_tab_control->SetAcceleratorsMode		(false);
	}

	bool res =  inherited::OnKeyboard(dik, keyboard_action);

	m_root_tab_control->SetAcceleratorsMode		(true);

	return			res;
}
示例#2
0
IC int PLC_calc	(Fvector& P, Fvector& N, light* L, float energy, Fvector& O)
{
	float	E		= PLC_energy(P,N,L,energy);
	float	C1		= clampr(Device.vCameraPosition.distance_to_sqr(P)/S_distance2,	0.f,1.f);
	float	C2		= clampr(O.distance_to_sqr(P)/S_fade2,							0.f,1.f);
	float	A		= 1.f-1.5f*E*(1.f-C1)*(1.f-C2);
	return			iCeil(255.f*A);
}
void CRenderTarget::phase_pp		()
{
	// combination/postprocess
	u_setrt				( Device.dwWidth,Device.dwHeight,HW.pBaseRT,NULL,NULL,HW.pBaseZB);
	//	Element 0 for for normal post-process
	//	Element 4 for color map post-process
	bool	bCMap = u_need_CM();
	//RCache.set_Element	(s_postprocess->E[bCMap ? 4 : 0]);
	if( !RImplementation.o.dx10_msaa )
	{
		//		RCache.set_Shader	(s_postprocess	);
		RCache.set_Element	(s_postprocess->E[bCMap ? 4 : 0]);
	}
	else
	{
		//		RCache.set_Shader( s_postprocess_msaa );
		RCache.set_Element	(s_postprocess_msaa->E[bCMap ? 4 : 0]);
	}

	int		gblend		= clampr		(iFloor((1-param_gray)*255.f),0,255);
	int		nblend		= clampr		(iFloor((1-param_noise)*255.f),0,255);
	u32					p_color			= subst_alpha		(param_color_base,nblend);
	u32					p_gray			= subst_alpha		(param_color_gray,gblend);
	Fvector				p_brightness	= param_color_add	;
	// Msg				("param_gray:%f(%d),param_noise:%f(%d)",param_gray,gblend,param_noise,nblend);
	// Msg				("base: %d,%d,%d",	color_get_R(p_color),		color_get_G(p_color),		color_get_B(p_color));
	// Msg				("gray: %d,%d,%d",	color_get_R(p_gray),		color_get_G(p_gray),		color_get_B(p_gray));
	// Msg				("add:  %d,%d,%d",	color_get_R(p_brightness),	color_get_G(p_brightness),	color_get_B(p_brightness));
	
	// Draw full-screen quad textured with our scene image
	u32		Offset;
	float	_w			= float(Device.dwWidth);
	float	_h			= float(Device.dwHeight);
	
	Fvector2			n0,n1,r0,r1,l0,l1;
	u_calc_tc_duality_ss	(r0,r1,l0,l1);
	u_calc_tc_noise			(n0,n1);

	// Fill vertex buffer
	float				du	= ps_r1_pps_u, dv = ps_r1_pps_v;
	TL_2c3uv* pv			= (TL_2c3uv*) RCache.Vertex.Lock	(4,g_postprocess.stride(),Offset);
	pv->set(du+0,			dv+float(_h),	p_color, p_gray, r0.x, r1.y, l0.x, l1.y, n0.x, n1.y);	pv++;
	pv->set(du+0,			dv+0,			p_color, p_gray, r0.x, r0.y, l0.x, l0.y, n0.x, n0.y);	pv++;
	pv->set(du+float(_w),	dv+float(_h),	p_color, p_gray, r1.x, r1.y, l1.x, l1.y, n1.x, n1.y);	pv++;
	pv->set(du+float(_w),	dv+0,			p_color, p_gray, r1.x, r0.y, l1.x, l0.y, n1.x, n0.y);	pv++;
	RCache.Vertex.Unlock										(4,g_postprocess.stride());

	// Actual rendering
	static	shared_str	s_brightness	= "c_brightness";
	static	shared_str	s_colormap		= "c_colormap";
	RCache.set_c		( s_brightness, p_brightness.x, p_brightness.y, p_brightness.z, 0 );
	RCache.set_c		(s_colormap, param_color_map_influence,param_color_map_interpolate,0,0);
	RCache.set_Geometry	(g_postprocess);
	RCache.Render		(D3DPT_TRIANGLELIST,Offset,0,4,0,2);
}
示例#4
0
void CEffect_Thunderbolt::OnFrame(shared_str id, float period, float duration)
{
	BOOL enabled			= !!(id.size());
	if (bEnabled!=enabled){
    	bEnabled			= enabled;
	    next_lightning_time = Device.fTimeGlobal+period+Random.randF(-period*0.5f,period*0.5f);
    }else if (bEnabled&&(Device.fTimeGlobal>next_lightning_time)){ 
    	if (state==stIdle && !!(id.size())) Bolt(id,period,duration);
    }
	if (state==stWorking){
    	if (current_time>life_time) state = stIdle;
    	current_time	+= Device.fTimeDelta;
		Fvector fClr;		
		int frame;
		u32 uClr		= current->color_anim->CalculateRGB(current_time/life_time,frame);
		fClr.set		(
			clampr(float(color_get_R(uClr)/255.f), 0.f, 1.f),
			clampr(float(color_get_G(uClr)/255.f), 0.f, 1.f),
			clampr(float(color_get_B(uClr)/255.f), 0.f, 1.f)
		);

        lightning_phase	= 1.5f*(current_time/life_time);
        clamp			(lightning_phase,0.f,1.f);

		CEnvironment&	environment = g_pGamePersistent->Environment();
		
		Fvector&		sky_color = environment.CurrentEnv->sky_color;
        sky_color.mad	( fClr, environment.p_sky_color );
		clamp			( sky_color.x, 0.f, 1.f );
		clamp			( sky_color.y, 0.f, 1.f );
		clamp			( sky_color.z, 0.f, 1.f );

        environment.CurrentEnv->sun_color.mad(fClr,environment.p_sun_color);
		environment.CurrentEnv->fog_color.mad(fClr,environment.p_fog_color);

		if (::Render->get_generation()==IRender_interface::GENERATION_R2)	{
			R_ASSERT	( _valid(current_direction) );
			g_pGamePersistent->Environment().CurrentEnv->sun_dir = current_direction;
			VERIFY2(g_pGamePersistent->Environment().CurrentEnv->sun_dir.y<0,"Invalid sun direction settings while CEffect_Thunderbolt");

		} 
    }
}
示例#5
0
void CEnvironment::OnFrame()
{
#ifdef _EDITOR
	SetGameTime				(fGameTime+Device.fTimeDelta*fTimeFactor,fTimeFactor);
    if (fsimilar(ed_to_time,DAY_LENGTH)&&fsimilar(ed_from_time,0.f)){
	    if (fGameTime>DAY_LENGTH)	fGameTime-=DAY_LENGTH;
    }else{
	    if (fGameTime>ed_to_time){	
        	fGameTime=fGameTime-ed_to_time+ed_from_time;
            Current[0]=Current[1]=0;
        }
    	if (fGameTime<ed_from_time){	
        	fGameTime=ed_from_time;
            Current[0]=Current[1]=0;
        }
    }
	if (!psDeviceFlags.is(rsEnvironment))		return;
#else
	if (!g_pGameLevel)		return;
#endif

//	if (pInput->iGetAsyncKeyState(DIK_O))		SetWeatherFX("surge_day"); 
	float					current_weight;
	lerp					(current_weight);

	//	Igor. Dynamic sun position. 
	if ( !::Render->is_sun_static())
		calculate_dynamic_sun_dir();

#ifndef MASTER_GOLD
	if(CurrentEnv->sun_dir.y>0)
	{
		Log("CurrentEnv->sun_dir", CurrentEnv->sun_dir);
//		Log("current_weight", current_weight);
//		Log("mpower", mpower);

		Log("Current[0]->sun_dir", Current[0]->sun_dir);
		Log("Current[1]->sun_dir", Current[1]->sun_dir);

	}
	VERIFY2						(CurrentEnv->sun_dir.y<0,"Invalid sun direction settings in lerp");
#endif // #ifndef MASTER_GOLD

	PerlinNoise1D->SetFrequency		(wind_gust_factor*MAX_NOISE_FREQ);
	wind_strength_factor			= clampr(PerlinNoise1D->GetContinious(Device.fTimeGlobal)+0.5f,0.f,1.f); 

    shared_str l_id						=	(current_weight<0.5f)?Current[0]->lens_flare_id:Current[1]->lens_flare_id;
	eff_LensFlare->OnFrame				(l_id);
	shared_str t_id						=	(current_weight<0.5f)?Current[0]->tb_id:Current[1]->tb_id;
    eff_Thunderbolt->OnFrame			(t_id,CurrentEnv->bolt_period,CurrentEnv->bolt_duration);
	eff_Rain->OnFrame					();

	// ******************** Environment params (setting)
	m_pRender->OnFrame(*this);
}
示例#6
0
r_aabb_ssa		r_pixel_calculator::calculate	(dxRender_Visual* V)	{
	r_aabb_ssa	result			= {0};
	float		area			= float(_sqr(rt_dimensions));

	// 
	u32	id				[6]		;
	for (u32 face=0; face<6; face++)	{
		// setup matrices
		Fmatrix						mProject,mView	;
		Fvector						vFrom			;
		Fbox						aabb			;

		// camera - left-to-right
		mView.build_camera_dir		(vFrom.invert(cmDir[face]).mul(100.f),	cmDir[face],	cmNorm[face])	;
		aabb.xform					(V->vis.box,mView);
		D3DXMatrixOrthoOffCenterLH	( (D3DXMATRIX*)&mProject, aabb.min.x, aabb.max.x, aabb.min.y, aabb.max.y, aabb.min.z, aabb.max.z );
		RCache.set_xform_world		(Fidentity);
		RCache.set_xform_view		(mView);
		RCache.set_xform_project	(mProject);

		// render-0
		Device.Clear				();	// clear-ZB
		RCache.set_Shader			(V->shader);
		V->Render					(1.f);

		// render-1
		RImplementation.HWOCC.occq_begin	(id[face]);
		V->Render							(1.f);
		RImplementation.HWOCC.occq_end		(id[face]);
	}

	// 
	for (u32 it=0; it<6; it++)	{
		float	pixels	= (float)RImplementation.HWOCC.occq_get	(id[it]);
		float	coeff	= clampr(pixels/area,float(0),float(1));
		Msg		("[%d]ssa_c: %1.3f,%f/%f",it,coeff,pixels,area);
		result.ssa	[it]= (u8)clampr(iFloor(coeff*255.f+0.5f),int(0),int(255));
	}

	return result	;
}
示例#7
0
void random_dir(Fvector& tgt_dir, const Fvector& src_dir, float dispersion)
{
	float sigma			= dispersion/3.f;
	float alpha			= clampr		(_nrand(sigma),-dispersion,dispersion);
	float theta			= Random.randF	(0,PI);
	float r 			= tan			(alpha);
	Fvector 			U,V,T;
	Fvector::generate_orthonormal_basis	(src_dir,U,V);
	U.mul				(r*_sin(theta));
	V.mul				(r*_cos(theta));
	T.add				(U,V);
	tgt_dir.add			(src_dir,T).normalize();
}
示例#8
0
void FProgressive::Render	(float LOD)
{
#if RENDER==R_R2
	if (m_fast && RImplementation.phase==CRender::PHASE_SMAP)
	{
		int lod_id			= iFloor((1.f-clampr(LOD,0.f,1.f))*float(xSWI->count-1)+0.5f);
		VERIFY				(lod_id>=0 && lod_id<int(xSWI->count));
		FSlideWindow& SW	= xSWI->sw[lod_id];
		RCache.set_Geometry	(m_fast->rm_geom);
		RCache.Render		(D3DPT_TRIANGLELIST,m_fast->vBase,0,SW.num_verts,m_fast->iBase+SW.offset,SW.num_tris);
		RCache.stat.r.s_static.add	(SW.num_verts);
	} else {
		int lod_id		= last_lod;
		if (LOD>=0.f){
			clamp			(LOD,0.f,1.f);
			lod_id			= iFloor((1.f-LOD)*float(nSWI.count-1)+0.5f);
			last_lod		= lod_id;
		}
		VERIFY				(lod_id>=0 && lod_id<int(nSWI.count));
		FSlideWindow& SW	= nSWI.sw[lod_id];
		RCache.set_Geometry	(rm_geom);
		RCache.Render		(D3DPT_TRIANGLELIST,vBase,0,SW.num_verts,iBase+SW.offset,SW.num_tris);
		RCache.stat.r.s_static.add	(SW.num_verts);
	}
#else
	int lod_id		= last_lod;
	if (LOD>=0.f){
		clamp		(LOD,0.f,1.f);
		lod_id		= iFloor((1.f-LOD)*float(nSWI.count-1)+0.5f);
		last_lod	= lod_id;
	}
	VERIFY						(lod_id>=0 && lod_id<int(nSWI.count));
	FSlideWindow& SW			= nSWI.sw[lod_id];
	RCache.set_Geometry			(rm_geom);
	RCache.Render				(D3DPT_TRIANGLELIST,vBase,0,SW.num_verts,iBase+SW.offset,SW.num_tris);
	RCache.stat.r.s_static.add	(SW.num_verts);
#endif
}
示例#9
0
CRenderTarget::CRenderTarget		()
{
	param_blur			= 0.f;
	param_gray			= 0.f;
	param_noise			= 0.f;
	param_duality_h		= 0.f;
	param_duality_v		= 0.f;
	param_noise_fps		= 25.f;
	param_noise_scale	= 1.f;

	im_noise_time		= 1/100;
	im_noise_shift_w	= 0;
	im_noise_shift_h	= 0;

	param_color_base	= color_rgba(127,127,127,	0);
	param_color_gray	= color_rgba(85,85,85,		0);
	param_color_add		= color_rgba(0,0,0,			0);

	dwAccumulatorClearMark			= 0;
	Device.Resources->Evict			();

	// Blenders
	b_occq							= xr_new<CBlender_light_occq>			();
	b_accum_mask					= xr_new<CBlender_accum_direct_mask>	();
	b_accum_direct					= xr_new<CBlender_accum_direct>			();
	b_accum_point					= xr_new<CBlender_accum_point>			();
	b_accum_spot					= xr_new<CBlender_accum_spot>			();
	b_accum_reflected				= xr_new<CBlender_accum_reflected>		();
	b_bloom							= xr_new<CBlender_bloom_build>			();
	b_luminance						= xr_new<CBlender_luminance>			();
	b_combine						= xr_new<CBlender_combine>				();

	//	NORMAL
	{
		u32		w=Device.dwWidth, h=Device.dwHeight;
		rt_Position.create			(r2_RT_P,		w,h,D3DFMT_A16B16G16R16F);
		rt_Normal.create			(r2_RT_N,		w,h,D3DFMT_A16B16G16R16F);

		// select albedo & accum
		if (RImplementation.o.mrtmixdepth)	
		{
			// NV50
			rt_Color.create			(r2_RT_albedo,	w,h,D3DFMT_A8R8G8B8		);
			rt_Accumulator.create	(r2_RT_accum,	w,h,D3DFMT_A16B16G16R16F);
		}
		else		
		{
			// can't - mix-depth
			if (RImplementation.o.fp16_blend) {
				// NV40
				rt_Color.create				(r2_RT_albedo,		w,h,D3DFMT_A16B16G16R16F);	// expand to full
				rt_Accumulator.create		(r2_RT_accum,		w,h,D3DFMT_A16B16G16R16F);
			} else {
				// R4xx, no-fp-blend,-> albedo_wo
				VERIFY						(RImplementation.o.albedo_wo);
				rt_Color.create				(r2_RT_albedo,		w,h,D3DFMT_A8R8G8B8		);	// normal
				rt_Accumulator.create		(r2_RT_accum,		w,h,D3DFMT_A16B16G16R16F);
				rt_Accumulator_temp.create	(r2_RT_accum_temp,	w,h,D3DFMT_A16B16G16R16F);
			}
		}

		// generic(LDR) RTs
		rt_Generic_0.create			(r2_RT_generic0,w,h,D3DFMT_A8R8G8B8		);
		rt_Generic_1.create			(r2_RT_generic1,w,h,D3DFMT_A8R8G8B8		);
	}

	// OCCLUSION
	s_occq.create					(b_occq,		"r2\\occq");

	// DIRECT (spot)
	D3DFORMAT						depth_format	= (D3DFORMAT)RImplementation.o.HW_smap_FORMAT;

	if (RImplementation.o.HW_smap)
	{
		D3DFORMAT	nullrt				= D3DFMT_R5G6B5;
		if (RImplementation.o.nullrt)	nullrt	= (D3DFORMAT)MAKEFOURCC('N','U','L','L');

		u32	size					=RImplementation.o.smapsize	;
		rt_smap_depth.create		(r2_RT_smap_depth,			size,size,depth_format	);
		rt_smap_surf.create			(r2_RT_smap_surf,			size,size,nullrt		);
		rt_smap_ZB					= NULL;
		s_accum_mask.create			(b_accum_mask,				"r2\\accum_mask");
		s_accum_direct.create		(b_accum_direct,			"r2\\accum_direct");
	}
	else
	{
		u32	size					=RImplementation.o.smapsize	;
		rt_smap_surf.create			(r2_RT_smap_surf,			size,size,D3DFMT_R32F);
		rt_smap_depth				= NULL;
		R_CHK						(HW.pDevice->CreateDepthStencilSurface	(size,size,D3DFMT_D24X8,D3DMULTISAMPLE_NONE,0,TRUE,&rt_smap_ZB,NULL));
		s_accum_mask.create			(b_accum_mask,				"r2\\accum_mask");
		s_accum_direct.create		(b_accum_direct,			"r2\\accum_direct");
	}

	// POINT
	{
		s_accum_point.create		(b_accum_point,				"r2\\accum_point_s");
		accum_point_geom_create		();
		g_accum_point.create		(D3DFVF_XYZ,				g_accum_point_vb, g_accum_point_ib);
		accum_omnip_geom_create		();
		g_accum_omnipart.create		(D3DFVF_XYZ,				g_accum_omnip_vb, g_accum_omnip_ib);
	}

	// SPOT
	{
		s_accum_spot.create			(b_accum_spot,				"r2\\accum_spot_s",	"lights\\lights_spot01");
		accum_spot_geom_create		();
		g_accum_spot.create			(D3DFVF_XYZ,				g_accum_spot_vb, g_accum_spot_ib);
	}

	// REFLECTED
	{
		s_accum_reflected.create	(b_accum_reflected,			"r2\\accum_refl");
	}

	// BLOOM
	{
		D3DFORMAT	fmt				= D3DFMT_A8R8G8B8;			//;		// D3DFMT_X8R8G8B8
		u32	w=BLOOM_size_X, h=BLOOM_size_Y;
		u32 fvf_build				= D3DFVF_XYZRHW|D3DFVF_TEX4|D3DFVF_TEXCOORDSIZE2(0)|D3DFVF_TEXCOORDSIZE2(1)|D3DFVF_TEXCOORDSIZE2(2)|D3DFVF_TEXCOORDSIZE2(3);
		u32 fvf_filter				= (u32)D3DFVF_XYZRHW|D3DFVF_TEX8|D3DFVF_TEXCOORDSIZE4(0)|D3DFVF_TEXCOORDSIZE4(1)|D3DFVF_TEXCOORDSIZE4(2)|D3DFVF_TEXCOORDSIZE4(3)|D3DFVF_TEXCOORDSIZE4(4)|D3DFVF_TEXCOORDSIZE4(5)|D3DFVF_TEXCOORDSIZE4(6)|D3DFVF_TEXCOORDSIZE4(7);
		rt_Bloom_1.create			(r2_RT_bloom1,	w,h,		fmt);
		rt_Bloom_2.create			(r2_RT_bloom2,	w,h,		fmt);
		g_bloom_build.create		(fvf_build,		RCache.Vertex.Buffer(), RCache.QuadIB);
		g_bloom_filter.create		(fvf_filter,	RCache.Vertex.Buffer(), RCache.QuadIB);
		s_bloom_dbg_1.create		("effects\\screen_set",		r2_RT_bloom1);
		s_bloom_dbg_2.create		("effects\\screen_set",		r2_RT_bloom2);
		s_bloom.create				(b_bloom,					"r2\\bloom");
		f_bloom_factor				= 0.5f;
	}

	// TONEMAP
	{
		rt_LUM_64.create			(r2_RT_luminance_t64,	64, 64,	D3DFMT_A16B16G16R16F	);
		rt_LUM_8.create				(r2_RT_luminance_t8,	8,	8,	D3DFMT_A16B16G16R16F	);
		s_luminance.create			(b_luminance,				"r2\\luminance");
		f_luminance_adapt			= 0.5f;

		t_LUM_src.create			(r2_RT_luminance_src);
		t_LUM_dest.create			(r2_RT_luminance_cur);

		// create pool
		for (u32 it=0; it<4; it++)	{
			string256					name;
			sprintf						(name,"%s_%d",	r2_RT_luminance_pool,it	);
			rt_LUM_pool[it].create		(name,	1,	1,	D3DFMT_R32F				);
			u_setrt						(rt_LUM_pool[it],	0,	0,	0			);
			CHK_DX						(HW.pDevice->Clear( 0L, NULL, D3DCLEAR_TARGET,	0x7f7f7f7f,	1.0f, 0L));
		}
		u_setrt						( Device.dwWidth,Device.dwHeight,HW.pBaseRT,NULL,NULL,HW.pBaseZB);
	}

	// COMBINE
	{
		static D3DVERTEXELEMENT9 dwDecl[] =
		{
			{ 0, 0,  D3DDECLTYPE_FLOAT4,	D3DDECLMETHOD_DEFAULT, 	D3DDECLUSAGE_POSITION,	0 },	// pos+uv
			D3DDECL_END()
		};
		s_combine.create					(b_combine,					"r2\\combine");
		s_combine_dbg_0.create				("effects\\screen_set",		r2_RT_smap_surf		);	
		s_combine_dbg_1.create				("effects\\screen_set",		r2_RT_luminance_t8	);
		s_combine_dbg_Accumulator.create	("effects\\screen_set",		r2_RT_accum			);
		g_combine_VP.create					(dwDecl,		RCache.Vertex.Buffer(), RCache.QuadIB);
		g_combine.create					(FVF::F_TL,		RCache.Vertex.Buffer(), RCache.QuadIB);
		g_combine_2UV.create				(FVF::F_TL2uv,	RCache.Vertex.Buffer(), RCache.QuadIB);

		u32 fvf_aa_blur				= D3DFVF_XYZRHW|D3DFVF_TEX4|D3DFVF_TEXCOORDSIZE2(0)|D3DFVF_TEXCOORDSIZE2(1)|D3DFVF_TEXCOORDSIZE2(2)|D3DFVF_TEXCOORDSIZE2(3);
		g_aa_blur.create			(fvf_aa_blur,	RCache.Vertex.Buffer(), RCache.QuadIB);

		u32 fvf_aa_AA				= D3DFVF_XYZRHW|D3DFVF_TEX7|D3DFVF_TEXCOORDSIZE2(0)|D3DFVF_TEXCOORDSIZE2(1)|D3DFVF_TEXCOORDSIZE2(2)|D3DFVF_TEXCOORDSIZE2(3)|D3DFVF_TEXCOORDSIZE2(4)|D3DFVF_TEXCOORDSIZE4(5)|D3DFVF_TEXCOORDSIZE4(6);
		g_aa_AA.create				(fvf_aa_AA,		RCache.Vertex.Buffer(), RCache.QuadIB);

		t_envmap_0.create			(r2_T_envs0);
		t_envmap_1.create			(r2_T_envs1);
	}

	// Build textures
	{
		// Build material(s)
		{
			// Surface
			R_CHK						(D3DXCreateVolumeTexture(HW.pDevice,TEX_material_LdotN,TEX_material_LdotH,4,1,0,D3DFMT_A8L8,D3DPOOL_MANAGED,&t_material_surf));
			t_material					= Device.Resources->_CreateTexture(r2_material);
			t_material->surface_set		(t_material_surf);

			// Fill it (addr: x=dot(L,N),y=dot(L,H))
			D3DLOCKED_BOX				R;
			R_CHK						(t_material_surf->LockBox	(0,&R,0,0));
			for (u32 slice=0; slice<4; slice++)
			{
				for (u32 y=0; y<TEX_material_LdotH; y++)
				{
					for (u32 x=0; x<TEX_material_LdotN; x++)
					{
						u16*	p	=	(u16*)		(LPBYTE (R.pBits) + slice*R.SlicePitch + y*R.RowPitch + x*2);
						float	ld	=	float(x)	/ float	(TEX_material_LdotN-1);
						float	ls	=	float(y)	/ float	(TEX_material_LdotH-1) + EPS_S;
						ls			*=	powf(ld,1/32.f);
						float	fd,fs;

						switch	(slice)
						{
						case 0:	{ // looks like OrenNayar
							fd	= powf(ld,0.75f);		// 0.75
							fs	= powf(ls,16.f)*.5f;
								}	break;
						case 1:	{// looks like Blinn
							fd	= powf(ld,0.90f);		// 0.90
							fs	= powf(ls,24.f);
								}	break;
						case 2:	{ // looks like Phong
							fd	= ld;					// 1.0
							fs	= powf(ls*1.01f,128.f	);
								}	break;
						case 3:	{ // looks like Metal
							float	s0	=	_abs	(1-_abs	(0.05f*_sin(33.f*ld)+ld-ls));
							float	s1	=	_abs	(1-_abs	(0.05f*_cos(33.f*ld*ls)+ld-ls));
							float	s2	=	_abs	(1-_abs	(ld-ls));
							fd		=	ld;				// 1.0
							fs		=	powf	(_max(_max(s0,s1),s2), 24.f);
							fs		*=	powf	(ld,1/7.f);
								}	break;
						default:
							fd	= fs = 0;
						}
						s32		_d	=	clampr	(iFloor	(fd*255.5f),	0,255);
						s32		_s	=	clampr	(iFloor	(fs*255.5f),	0,255);
						if ((y==(TEX_material_LdotH-1)) && (x==(TEX_material_LdotN-1)))	{ _d = 255; _s=255;	}
						*p			=	u16		(_s*256 + _d);
					}
				}
			}
			R_CHK		(t_material_surf->UnlockBox	(0));
			// #ifdef DEBUG
			// R_CHK	(D3DXSaveTextureToFile	("x:\\r2_material.dds",D3DXIFF_DDS,t_material_surf,0));
			// #endif
		}

		// Build noise table
		if (1)
		{
			// Surfaces
			D3DLOCKED_RECT				R[TEX_jitter_count];
			for (int it=0; it<TEX_jitter_count; it++)
			{
				string_path					name;
				sprintf						(name,"%s%d",r2_jitter,it);
				R_CHK	(D3DXCreateTexture	(HW.pDevice,TEX_jitter,TEX_jitter,1,0,D3DFMT_Q8W8V8U8,D3DPOOL_MANAGED,&t_noise_surf[it]));
				t_noise[it]					= Device.Resources->_CreateTexture	(name);
				t_noise[it]->surface_set	(t_noise_surf[it]);
				R_CHK						(t_noise_surf[it]->LockRect	(0,&R[it],0,0));
			}

			// Fill it,
			for (u32 y=0; y<TEX_jitter; y++)
			{
				for (u32 x=0; x<TEX_jitter; x++)
				{
					DWORD	data	[TEX_jitter_count];
					generate_jitter	(data,TEX_jitter_count);
					for (u32 it=0; it<TEX_jitter_count; it++)
					{
						u32*	p	=	(u32*)	(LPBYTE (R[it].pBits) + y*R[it].Pitch + x*4);
								*p	=	data	[it];
					}
				}
			}
			for (int it=0; it<TEX_jitter_count; it++)	{
				R_CHK						(t_noise_surf[it]->UnlockRect(0));
			}
		}
	}

	// PP
	s_postprocess.create				("postprocess");
	g_postprocess.create				(D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_SPECULAR|D3DFVF_TEX3,RCache.Vertex.Buffer(),RCache.QuadIB);

	// Menu
	s_menu.create						("distort");
	g_menu.create						(FVF::F_TL,RCache.Vertex.Buffer(),RCache.QuadIB);

	// 
	dwWidth		= Device.dwWidth;
	dwHeight	= Device.dwHeight;
}
示例#10
0
void CEnvironment::OnFrame()
{
#ifdef _EDITOR
	SetGameTime				(fGameTime+Device.fTimeDelta*fTimeFactor,fTimeFactor);
    if (fsimilar(ed_to_time,DAY_LENGTH)&&fsimilar(ed_from_time,0.f)){
	    if (fGameTime>DAY_LENGTH)	fGameTime-=DAY_LENGTH;
    }else{
	    if (fGameTime>ed_to_time){	
        	fGameTime=fGameTime-ed_to_time+ed_from_time;
            Current[0]=Current[1]=0;
        }
    	if (fGameTime<ed_from_time){	
        	fGameTime=ed_from_time;
            Current[0]=Current[1]=0;
        }
    }
	if (!psDeviceFlags.is(rsEnvironment))		return;
#else
	if (!g_pGameLevel)		return;
#endif

//	if (pInput->iGetAsyncKeyState(DIK_O))		SetWeatherFX("surge_day"); 

	if (bWFX&&(wfx_time<=0.f)) StopWFX();

	SelectEnvs				(fGameTime);
    VERIFY					(Current[0]&&Current[1]);

	float current_weight	= TimeWeight(fGameTime,Current[0]->exec_time,Current[1]->exec_time);

	// modifiers
	CEnvModifier			EM;
	EM.far_plane			= 0;
	EM.fog_color.set		( 0,0,0 );
	EM.fog_density			= 0;
	EM.ambient.set			( 0,0,0 );
	EM.sky_color.set		( 0,0,0 );
	EM.hemi_color.set		( 0,0,0 );
	Fvector	view			= Device.vCameraPosition;
	float	mpower			= 0;
	for (xr_vector<CEnvModifier>::iterator mit=Modifiers.begin(); mit!=Modifiers.end(); mit++)
		mpower				+= EM.sum(*mit,view);

	// final lerp
	CurrentEnv.lerp				(this,*Current[0],*Current[1],current_weight,EM,mpower);
#ifndef SUN_DIR_NOT_DEBUG
	if(CurrentEnv.sun_dir.y>0)
	{
		Log("CurrentEnv.sun_dir", CurrentEnv.sun_dir);
		Log("current_weight", current_weight);
		Log("mpower", mpower);

		Log("Current[0]->sun_dir", Current[0]->sun_dir);
		Log("Current[1]->sun_dir", Current[1]->sun_dir);

	}
#endif
	VERIFY2						(CurrentEnv.sun_dir.y<0,"Invalid sun direction settings in lerp");

	if (::Render->get_generation()==IRender_interface::GENERATION_R2){
		//. very very ugly hack
		if (HW.Caps.raster_major >= 3 && HW.Caps.geometry.bVTF){
			// tonemapping in VS
			CurrentEnv.sky_r_textures.push_back		(mk_pair(u32(D3DVERTEXTEXTURESAMPLER0),tonemap));	//. hack
			CurrentEnv.sky_r_textures_env.push_back	(mk_pair(u32(D3DVERTEXTEXTURESAMPLER0),tonemap));	//. hack
			CurrentEnv.clouds_r_textures.push_back	(mk_pair(u32(D3DVERTEXTEXTURESAMPLER0),tonemap));	//. hack
		} else {
			// tonemapping in PS
			CurrentEnv.sky_r_textures.push_back		(mk_pair(2,tonemap));								//. hack
			CurrentEnv.sky_r_textures_env.push_back	(mk_pair(2,tonemap));								//. hack
			CurrentEnv.clouds_r_textures.push_back	(mk_pair(2,tonemap));								//. hack
		}
		
	}

	//. Setup skybox textures, somewhat ugly
	IDirect3DBaseTexture9*	e0	= CurrentEnv.sky_r_textures[0].second->surface_get();
	IDirect3DBaseTexture9*	e1	= CurrentEnv.sky_r_textures[1].second->surface_get();
	
	tsky0->surface_set		(e0);	_RELEASE(e0);
	tsky1->surface_set		(e1);	_RELEASE(e1);

	PerlinNoise1D->SetFrequency		(wind_gust_factor*MAX_NOISE_FREQ);
	wind_strength_factor			= clampr(PerlinNoise1D->GetContinious(Device.fTimeGlobal)+0.5f,0.f,1.f); 

    int l_id							=	(current_weight<0.5f)?Current[0]->lens_flare_id:Current[1]->lens_flare_id;
	eff_LensFlare->OnFrame				(l_id);
	int t_id							=	(current_weight<0.5f)?Current[0]->tb_id:Current[1]->tb_id;
    eff_Thunderbolt->OnFrame			(t_id,CurrentEnv.bolt_period,CurrentEnv.bolt_duration);
	eff_Rain->OnFrame					();

	// ******************** Environment params (setting)
	CHK_DX(HW.pDevice->SetRenderState( D3DRS_FOGCOLOR,	color_rgba_f(CurrentEnv.fog_color.x,CurrentEnv.fog_color.y,CurrentEnv.fog_color.z,0) )); 
	CHK_DX(HW.pDevice->SetRenderState( D3DRS_FOGSTART,	*(u32 *)(&CurrentEnv.fog_near)	));
	CHK_DX(HW.pDevice->SetRenderState( D3DRS_FOGEND,	*(u32 *)(&CurrentEnv.fog_far)	));
}
示例#11
0
CRenderTarget::CRenderTarget		()
{
	param_blur			= 0.f;
	param_gray			= 0.f;
	param_noise			= 0.f;
	param_duality_h		= 0.f;
	param_duality_v		= 0.f;
	param_noise_fps		= 25.f;
	param_noise_scale	= 1.f;

	im_noise_time		= 1/100;
	im_noise_shift_w	= 0;
	im_noise_shift_h	= 0;

	param_color_base	= color_rgba(127,127,127,	0);
	param_color_gray	= color_rgba(85,85,85,		0);
	param_color_add.set( 0.0f, 0.0f, 0.0f );

	dwAccumulatorClearMark			= 0;
	dxRenderDeviceRender::Instance().Resources->Evict			();

	// Blenders
	b_occq							= new CBlender_light_occq();
	b_accum_mask					= new CBlender_accum_direct_mask();
	b_accum_direct					= new CBlender_accum_direct();
	b_accum_point					= new CBlender_accum_point();
	b_accum_spot					= new CBlender_accum_spot();
	b_accum_reflected				= new CBlender_accum_reflected();
	b_bloom							= new CBlender_bloom_build();
	b_ssao							= new CBlender_SSAO();
	b_luminance						= new CBlender_luminance();
	b_combine						= new CBlender_combine();

	//	NORMAL
	{
		u32		w=Device.dwWidth, h=Device.dwHeight;
		rt_Position.create			(r2_RT_P,		w,h,D3DFMT_A16B16G16R16F);
		rt_Normal.create			(r2_RT_N,		w,h,D3DFMT_A16B16G16R16F);

		// select albedo & accum
		if (RImplementation.o.mrtmixdepth)	
		{
			// NV50
			rt_Color.create			(r2_RT_albedo,	w,h,D3DFMT_A8R8G8B8		);
			rt_Accumulator.create	(r2_RT_accum,	w,h,D3DFMT_A16B16G16R16F);
		}
		else		
		{
			// can't - mix-depth
			if (RImplementation.o.fp16_blend) {
				// NV40
				rt_Color.create				(r2_RT_albedo,		w,h,D3DFMT_A16B16G16R16F);	// expand to full
				rt_Accumulator.create		(r2_RT_accum,		w,h,D3DFMT_A16B16G16R16F);
			} else {
				// R4xx, no-fp-blend,-> albedo_wo
				VERIFY						(RImplementation.o.albedo_wo);
				rt_Color.create				(r2_RT_albedo,		w,h,D3DFMT_A8R8G8B8		);	// normal
				rt_Accumulator.create		(r2_RT_accum,		w,h,D3DFMT_A16B16G16R16F);
				rt_Accumulator_temp.create	(r2_RT_accum_temp,	w,h,D3DFMT_A16B16G16R16F);
			}
		}

		// generic(LDR) RTs
		rt_Generic_0.create			(r2_RT_generic0,w,h,D3DFMT_A8R8G8B8		);
		rt_Generic_1.create			(r2_RT_generic1,w,h,D3DFMT_A8R8G8B8		);
		//	Igor: for volumetric lights
		//rt_Generic_2.create			(r2_RT_generic2,w,h,D3DFMT_A8R8G8B8		);
		//	temp: for higher quality blends
		if (RImplementation.o.advancedpp)
			rt_Generic_2.create			(r2_RT_generic2,w,h,D3DFMT_A16B16G16R16F);
	}

	// OCCLUSION
	s_occq.create					(b_occq,		"r2\\occq");

	// DIRECT (spot)
	D3DFORMAT						depth_format	= (D3DFORMAT)RImplementation.o.HW_smap_FORMAT;

	if (RImplementation.o.HW_smap)
	{
		D3DFORMAT	nullrt				= D3DFMT_R5G6B5;
		if (RImplementation.o.nullrt)	nullrt	= (D3DFORMAT)MAKEFOURCC('N','U','L','L');

		u32	size					=RImplementation.o.smapsize	;
		rt_smap_depth.create		(r2_RT_smap_depth,			size,size,depth_format	);
		rt_smap_surf.create			(r2_RT_smap_surf,			size,size,nullrt		);
		rt_smap_ZB					= NULL;
		s_accum_mask.create			(b_accum_mask,				"r2\\accum_mask");
		s_accum_direct.create		(b_accum_direct,			"r2\\accum_direct");
		if (RImplementation.o.advancedpp)
			s_accum_direct_volumetric.create("accum_volumetric_sun");
	}
	else
	{
		u32	size					=RImplementation.o.smapsize	;
		rt_smap_surf.create			(r2_RT_smap_surf,			size,size,D3DFMT_R32F);
		rt_smap_depth				= NULL;
		R_CHK						(HW.pDevice->CreateDepthStencilSurface	(size,size,D3DFMT_D24X8,D3DMULTISAMPLE_NONE,0,TRUE,&rt_smap_ZB,NULL));
		s_accum_mask.create			(b_accum_mask,				"r2\\accum_mask");
		s_accum_direct.create		(b_accum_direct,			"r2\\accum_direct");
		if (RImplementation.o.advancedpp)
			s_accum_direct_volumetric.create("accum_volumetric_sun");
	}

	// POINT
	{
		s_accum_point.create		(b_accum_point,				"r2\\accum_point_s");
		accum_point_geom_create		();
		g_accum_point.create		(D3DFVF_XYZ,				g_accum_point_vb, g_accum_point_ib);
		accum_omnip_geom_create		();
		g_accum_omnipart.create		(D3DFVF_XYZ,				g_accum_omnip_vb, g_accum_omnip_ib);
	}

	// SPOT
	{
		s_accum_spot.create			(b_accum_spot,				"r2\\accum_spot_s",	"lights\\lights_spot01");
		accum_spot_geom_create		();
		g_accum_spot.create			(D3DFVF_XYZ,				g_accum_spot_vb, g_accum_spot_ib);
	}

	{
		s_accum_volume.create("accum_volumetric", "lights\\lights_spot01");
		accum_volumetric_geom_create();
		g_accum_volumetric.create( D3DFVF_XYZ, g_accum_volumetric_vb, g_accum_volumetric_ib);
	}
			

	// REFLECTED
	{
		s_accum_reflected.create	(b_accum_reflected,			"r2\\accum_refl");
	}

	// BLOOM
	{
		D3DFORMAT	fmt				= D3DFMT_A8R8G8B8;			//;		// D3DFMT_X8R8G8B8
		u32	w=BLOOM_size_X, h=BLOOM_size_Y;
		u32 fvf_build				= D3DFVF_XYZRHW|D3DFVF_TEX4|D3DFVF_TEXCOORDSIZE2(0)|D3DFVF_TEXCOORDSIZE2(1)|D3DFVF_TEXCOORDSIZE2(2)|D3DFVF_TEXCOORDSIZE2(3);
		u32 fvf_filter				= (u32)D3DFVF_XYZRHW|D3DFVF_TEX8|D3DFVF_TEXCOORDSIZE4(0)|D3DFVF_TEXCOORDSIZE4(1)|D3DFVF_TEXCOORDSIZE4(2)|D3DFVF_TEXCOORDSIZE4(3)|D3DFVF_TEXCOORDSIZE4(4)|D3DFVF_TEXCOORDSIZE4(5)|D3DFVF_TEXCOORDSIZE4(6)|D3DFVF_TEXCOORDSIZE4(7);
		rt_Bloom_1.create			(r2_RT_bloom1,	w,h,		fmt);
		rt_Bloom_2.create			(r2_RT_bloom2,	w,h,		fmt);
		g_bloom_build.create		(fvf_build,		RCache.Vertex.Buffer(), RCache.QuadIB);
		g_bloom_filter.create		(fvf_filter,	RCache.Vertex.Buffer(), RCache.QuadIB);
		s_bloom_dbg_1.create		("effects\\screen_set",		r2_RT_bloom1);
		s_bloom_dbg_2.create		("effects\\screen_set",		r2_RT_bloom2);
		s_bloom.create				(b_bloom,					"r2\\bloom");
		f_bloom_factor				= 0.5f;
	}

	//HBAO
	if (RImplementation.o.ssao_opt_data)
	{
		u32		w = 0;
		u32		h = 0;
		if (RImplementation.o.ssao_half_data)
		{
			w = Device.dwWidth / 2;
			h = Device.dwHeight / 2;
		}
		else
		{
			w = Device.dwWidth;
			h = Device.dwHeight;
		}
		D3DFORMAT	fmt = HW.Caps.id_vendor==0x10DE?D3DFMT_R32F:D3DFMT_R16F;

		rt_half_depth.create		(r2_RT_half_depth, w, h, fmt);
		s_ssao.create				(b_ssao, "r2\\ssao");
	}

	//SSAO
	if (RImplementation.o.ssao_blur_on)
	{
		u32		w = Device.dwWidth, h = Device.dwHeight;
		rt_ssao_temp.create			(r2_RT_ssao_temp, w, h, D3DFMT_G16R16F);
		s_ssao.create				(b_ssao, "r2\\ssao");
	}

	// TONEMAP
	{
		rt_LUM_64.create			(r2_RT_luminance_t64,	64, 64,	D3DFMT_A16B16G16R16F	);
		rt_LUM_8.create				(r2_RT_luminance_t8,	8,	8,	D3DFMT_A16B16G16R16F	);
		s_luminance.create			(b_luminance,				"r2\\luminance");
		f_luminance_adapt			= 0.5f;

		t_LUM_src.create			(r2_RT_luminance_src);
		t_LUM_dest.create			(r2_RT_luminance_cur);

		// create pool
		for (u32 it=0; it<HW.Caps.iGPUNum*2; it++)	{
			string256					name;
			sprintf						(name,"%s_%d",	r2_RT_luminance_pool,it	);
			rt_LUM_pool[it].create		(name,	1,	1,	D3DFMT_R32F				);
			u_setrt						(rt_LUM_pool[it],	0,	0,	0			);
			CHK_DX						(HW.pDevice->Clear( 0L, NULL, D3DCLEAR_TARGET,	0x7f7f7f7f,	1.0f, 0L));
		}
		u_setrt						( Device.dwWidth,Device.dwHeight,HW.pBaseRT,NULL,NULL,HW.pBaseZB);
	}

	// COMBINE
	{
		static D3DVERTEXELEMENT9 dwDecl[] =
		{
			{ 0, 0,  D3DDECLTYPE_FLOAT4,	D3DDECLMETHOD_DEFAULT, 	D3DDECLUSAGE_POSITION,	0 },	// pos+uv
			{ 0, 16, D3DDECLTYPE_D3DCOLOR,	D3DDECLMETHOD_DEFAULT, 	D3DDECLUSAGE_COLOR,		0 },
			{ 0, 20, D3DDECLTYPE_FLOAT2,	D3DDECLMETHOD_DEFAULT, 	D3DDECLUSAGE_TEXCOORD,	0 },
			D3DDECL_END()
		};
		s_combine.create					(b_combine,					"r2\\combine");
		s_combine_volumetric.create			("combine_volumetric");
		s_combine_dbg_0.create				("effects\\screen_set",		r2_RT_smap_surf		);	
		s_combine_dbg_1.create				("effects\\screen_set",		r2_RT_luminance_t8	);
		s_combine_dbg_Accumulator.create	("effects\\screen_set",		r2_RT_accum			);
		g_combine_VP.create					(dwDecl,		RCache.Vertex.Buffer(), RCache.QuadIB);
		g_combine.create					(FVF::F_TL,		RCache.Vertex.Buffer(), RCache.QuadIB);
		g_combine_2UV.create				(FVF::F_TL2uv,	RCache.Vertex.Buffer(), RCache.QuadIB);

		u32 fvf_aa_blur				= D3DFVF_XYZRHW|D3DFVF_TEX4|D3DFVF_TEXCOORDSIZE2(0)|D3DFVF_TEXCOORDSIZE2(1)|D3DFVF_TEXCOORDSIZE2(2)|D3DFVF_TEXCOORDSIZE2(3);
		g_aa_blur.create			(fvf_aa_blur,	RCache.Vertex.Buffer(), RCache.QuadIB);

		u32 fvf_aa_AA				= D3DFVF_XYZRHW|D3DFVF_TEX7|D3DFVF_TEXCOORDSIZE2(0)|D3DFVF_TEXCOORDSIZE2(1)|D3DFVF_TEXCOORDSIZE2(2)|D3DFVF_TEXCOORDSIZE2(3)|D3DFVF_TEXCOORDSIZE2(4)|D3DFVF_TEXCOORDSIZE4(5)|D3DFVF_TEXCOORDSIZE4(6);
		g_aa_AA.create				(fvf_aa_AA,		RCache.Vertex.Buffer(), RCache.QuadIB);

		t_envmap_0.create			(r2_T_envs0);
		t_envmap_1.create			(r2_T_envs1);
	}

	// Build textures
	{
		// Build material(s)
		{
			// Surface
			R_CHK						(D3DXCreateVolumeTexture(HW.pDevice,TEX_material_LdotN,TEX_material_LdotH,4,1,0,D3DFMT_A8L8,D3DPOOL_MANAGED,&t_material_surf));
			t_material					= dxRenderDeviceRender::Instance().Resources->_CreateTexture(r2_material);
			t_material->surface_set		(t_material_surf);

			// Fill it (addr: x=dot(L,N),y=dot(L,H))
			D3DLOCKED_BOX				R;
			R_CHK						(t_material_surf->LockBox	(0,&R,0,0));
			for (u32 slice=0; slice<4; slice++)
			{
				for (u32 y=0; y<TEX_material_LdotH; y++)
				{
					for (u32 x=0; x<TEX_material_LdotN; x++)
					{
						u16*	p	=	(u16*)		(LPBYTE (R.pBits) + slice*R.SlicePitch + y*R.RowPitch + x*2);
						float	ld	=	float(x)	/ float	(TEX_material_LdotN-1);
						float	ls	=	float(y)	/ float	(TEX_material_LdotH-1) + EPS_S;
						ls			*=	powf(ld,1/32.f);
						float	fd,fs;

						switch	(slice)
						{
						case 0:	{ // looks like OrenNayar
							fd	= powf(ld,0.75f);		// 0.75
							fs	= powf(ls,16.f)*.5f;
								}	break;
						case 1:	{// looks like Blinn
							fd	= powf(ld,0.90f);		// 0.90
							fs	= powf(ls,24.f);
								}	break;
						case 2:	{ // looks like Phong
							fd	= ld;					// 1.0
							fs	= powf(ls*1.01f,128.f	);
								}	break;
						case 3:	{ // looks like Metal
							float	s0	=	_abs	(1-_abs	(0.05f*_sin(33.f*ld)+ld-ls));
							float	s1	=	_abs	(1-_abs	(0.05f*_cos(33.f*ld*ls)+ld-ls));
							float	s2	=	_abs	(1-_abs	(ld-ls));
							fd		=	ld;				// 1.0
							fs		=	powf	(_max(_max(s0,s1),s2), 24.f);
							fs		*=	powf	(ld,1/7.f);
								}	break;
						default:
							fd	= fs = 0;
						}
						s32		_d	=	clampr	(iFloor	(fd*255.5f),	0,255);
						s32		_s	=	clampr	(iFloor	(fs*255.5f),	0,255);
						if ((y==(TEX_material_LdotH-1)) && (x==(TEX_material_LdotN-1)))	{ _d = 255; _s=255;	}
						*p			=	u16		(_s*256 + _d);
					}
				}
			}
			R_CHK		(t_material_surf->UnlockBox	(0));
			// #ifdef DEBUG
			// R_CHK	(D3DXSaveTextureToFile	("x:\\r2_material.dds",D3DXIFF_DDS,t_material_surf,0));
			// #endif
		}

		// Build noise table
		if (1)
		{
			// Surfaces
			D3DLOCKED_RECT				R[TEX_jitter_count];
			for (int it1=0; it1<TEX_jitter_count-1; it1++)
			{
				string_path					name;
				sprintf						(name,"%s%d",r2_jitter,it1);
				R_CHK	(D3DXCreateTexture	(HW.pDevice,TEX_jitter,TEX_jitter,1,0,D3DFMT_Q8W8V8U8,D3DPOOL_MANAGED,&t_noise_surf[it1]));
				t_noise[it1]					= dxRenderDeviceRender::Instance().Resources->_CreateTexture	(name);
				t_noise[it1]->surface_set	(t_noise_surf[it1]);
				R_CHK						(t_noise_surf[it1]->LockRect	(0,&R[it1],0,0));
			}	

			// Fill it,
			for (u32 y=0; y<TEX_jitter; y++)
			{
				for (u32 x=0; x<TEX_jitter; x++)
				{
					DWORD	data	[TEX_jitter_count-1];
					generate_jitter	(data,TEX_jitter_count-1);
					for (u32 it2=0; it2<TEX_jitter_count-1; it2++)
					{
						u32*	p	=	(u32*)	(LPBYTE (R[it2].pBits) + y*R[it2].Pitch + x*4);
								*p	=	data	[it2];
					}
				}
			}
			
			for (int it3=0; it3<TEX_jitter_count-1; it3++)	{
				R_CHK						(t_noise_surf[it3]->UnlockRect(0));
			}		

			// generate HBAO jitter texture (last)
			int it = TEX_jitter_count - 1;
			string_path					name;
			sprintf						(name,"%s%d",r2_jitter,it);
			R_CHK	(D3DXCreateTexture	(HW.pDevice,TEX_jitter,TEX_jitter,1,0,D3DFMT_A32B32G32R32F,D3DPOOL_MANAGED,&t_noise_surf[it]));
			t_noise[it]					= dxRenderDeviceRender::Instance().Resources->_CreateTexture	(name);
			t_noise[it]->surface_set	(t_noise_surf[it]);
			R_CHK						(t_noise_surf[it]->LockRect	(0,&R[it],0,0));
			
			// Fill it,
			for (u32 y=0; y<TEX_jitter; y++)
			{
				for (u32 x=0; x<TEX_jitter; x++)
				{
					float numDir = 1.0f;
					switch (ps_r_ssao)
					{
						case 1: numDir = 4.0f; break;
						case 2: numDir = 6.0f; break;
						case 3: numDir = 8.0f; break;
					}
					float angle = 2 * PI * ::Random.randF(0.0f, 1.0f) / numDir;
					float dist = ::Random.randF(0.0f, 1.0f);
					//float dest[4];
					
					float*	p	=	(float*)	(LPBYTE (R[it].pBits) + y*R[it].Pitch + x*4*sizeof(float));
					*p = (float)(_cos(angle));
					*(p+1) = (float)(_sin(angle));
					*(p+2) = (float)(dist);
					*(p+3) = 0;
					
					//generate_hbao_jitter	(data,TEX_jitter*TEX_jitter);
				}
			}			
			R_CHK						(t_noise_surf[it]->UnlockRect(0));
		}
	}

	// PP
	s_postprocess.create				("postprocess");
	g_postprocess.create				(D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_SPECULAR|D3DFVF_TEX3,RCache.Vertex.Buffer(),RCache.QuadIB);

	// Menu
	s_menu.create						("distort");
	g_menu.create						(FVF::F_TL,RCache.Vertex.Buffer(),RCache.QuadIB);

	//	Igor: TMP
	//	Create an RT for online screenshot makining
	//u32		w = Device.dwWidth, h = Device.dwHeight;
	//HW.pDevice->CreateOffscreenPlainSurface(Device.dwWidth,Device.dwHeight,D3DFMT_A8R8G8B8,D3DPOOL_SYSTEMMEM,&pFB,NULL);
	//HW.pDevice->CreateOffscreenPlainSurface(Device.dwWidth,Device.dwHeight,rt_Color->fmt,D3DPOOL_SYSTEMMEM,&pFB,NULL);
	D3DSURFACE_DESC	desc;
	HW.pBaseRT->GetDesc(&desc);
	HW.pDevice->CreateOffscreenPlainSurface(Device.dwWidth,Device.dwHeight,desc.Format,D3DPOOL_SYSTEMMEM,&pFB,NULL);

	// 
	dwWidth		= Device.dwWidth;
	dwHeight	= Device.dwHeight;
}
示例#12
0
void dx103DFluidRenderer::CalculateLighting(const dx103DFluidData &FluidData, FogLighting  &LightData)
{
	m_lstRenderables.clear_not_free();

	LightData.Reset();

	const dx103DFluidData::Settings &VolumeSettings = FluidData.GetSettings();

	Fvector4 hemi_color = g_pGamePersistent->Environment().CurrentEnv->hemi_color;
	//hemi_color.mul(0.2f);
	hemi_color.mul(VolumeSettings.m_fHemi);
	LightData.m_vLightIntencity.set(hemi_color.x, hemi_color.y, hemi_color.z);
	LightData.m_vLightIntencity.add(g_pGamePersistent->Environment().CurrentEnv->ambient);

	const Fmatrix &Transform = FluidData.GetTransform();

	Fbox	box;
	box.min = Fvector3().set(-0.5f, -0.5f, -0.5f);
	box.max = Fvector3().set( 0.5f,  0.5f,  0.5f);
	box.xform(Transform);
	Fvector3	center;
	Fvector3	size;
	box.getcenter(center);
	box.getradius(size);


	// Traverse object database
	g_SpatialSpace->q_box
		(
		m_lstRenderables,
		0, //ISpatial_DB::O_ORDERED,
		STYPE_LIGHTSOURCE,
		center,
		size
		);

	u32 iNumRenderables = m_lstRenderables.size();
	// Determine visibility for dynamic part of scene
	for (u32 i=0; i<iNumRenderables; ++i)
	{
		ISpatial*	spatial		= m_lstRenderables[i];

		// Light
		light*	pLight = (light*) spatial->dcast_Light();
		VERIFY(pLight);

		if (pLight->flags.bStatic) continue;

		float	d	=	pLight->position.distance_to(Transform.c);

		float	R				= pLight->range + _max( size.x, _max( size.y, size.z ) );
		if ( d >= R )
			continue;

		Fvector3	LightIntencity;

		LightIntencity.set(pLight->color.r, pLight->color.g, pLight->color.b);

		//LightIntencity.mul(0.5f);

		//if (!pLight->flags.bStatic)
		//	LightIntencity.mul(0.5f);

		float	r	=	pLight->range;
		float	a	=	clampr(1.f - d/(r+EPS),0.f,1.f)*(pLight->flags.bStatic?1.f:2.f);

		LightIntencity.mul(a);

		LightData.m_vLightIntencity.add(LightIntencity);
	}

	//LightData.m_vLightIntencity.set( 1.0f, 0.5f, 0.0f);
	//LightData.m_vLightIntencity.set( 1.0f, 1.0f, 1.0f);
}
示例#13
0
void CSheduler::ProcessStep			()
{
	// Normal priority
	u32		dwTime					= Device.dwTimeGlobal;
	CTimer							eTimer;
	for (int i=0;!Items.empty() && Top().dwTimeForExecute < dwTime; ++i) {
		u32		delta_ms			= dwTime - Top().dwTimeForExecute;

		// Update
		Item	T					= Top	();
#ifdef DEBUG_SCHEDULER
		Msg		("SCHEDULER: process step [%s][%x][false]",*T.scheduled_name,T.Object);
#endif // DEBUG_SCHEDULER
		u32		Elapsed				= dwTime-T.dwTimeOfLastExecute;
		bool	condition;
		
		condition					= (NULL==T.Object || !T.Object->shedule_Needed());
		if (condition) {
			// Erase element
#ifdef DEBUG_SCHEDULER
			Msg						("SCHEDULER: process unregister [%s][%x][%s]",*T.scheduled_name,T.Object,"false");
#endif // DEBUG_SCHEDULER
//			if (T.Object)
//				Msg					("0x%08x UNREGISTERS because shedule_Needed() returned false",T.Object);
//			else
//				Msg					("UNREGISTERS unknown object");
			Pop						();
			continue;
		}

		// Insert into priority Queue
		Pop							();

		// Real update call
		// Msg						("------- %d:",Device.dwFrame);
#ifdef DEBUG
		T.Object->dbg_startframe	= Device.dwFrame;
		eTimer.Start				();
//		LPCSTR		_obj_name		= T.Object->shedule_Name().c_str();
#endif // DEBUG

		// Calc next update interval
		u32		dwMin				= _max(u32(30),T.Object->shedule.t_min);
		u32		dwMax				= (1000+T.Object->shedule.t_max)/2;
		float	scale				= T.Object->shedule_Scale	(); 
		u32		dwUpdate			= dwMin+iFloor(float(dwMax-dwMin)*scale);
		clamp	(dwUpdate,u32(_max(dwMin,u32(20))),dwMax);

		

		m_current_step_obj = T.Object;
//			try {
			T.Object->shedule_Update	(clampr(Elapsed,u32(1),u32(_max(u32(T.Object->shedule.t_max),u32(1000)))) );
			if (!m_current_step_obj)
			{
#ifdef DEBUG_SCHEDULER
				Msg						("SCHEDULER: process unregister (self unregistering) [%s][%x][%s]",*T.scheduled_name,T.Object,"false");
#endif // DEBUG_SCHEDULER
				continue;
			}
//			} catch (...) {
#ifdef DEBUG
//				Msg		("! xrSheduler: object '%s' raised an exception", _obj_name);
//				throw	;
#endif // DEBUG
//			}
		m_current_step_obj = NULL;

#ifdef DEBUG
//		u32	execTime				= eTimer.GetElapsed_ms		();
#endif // DEBUG

		// Fill item structure
		Item						TNext;
		TNext.dwTimeForExecute		= dwTime+dwUpdate;
		TNext.dwTimeOfLastExecute	= dwTime;
		TNext.Object				= T.Object;
		TNext.scheduled_name		= T.Object->shedule_Name();
		ItemsProcessed.push_back	(TNext);


#ifdef DEBUG
//		u32	execTime				= eTimer.GetElapsed_ms		();
		// VERIFY3					(T.Object->dbg_update_shedule == T.Object->dbg_startframe, "Broken sequence of calls to 'shedule_Update'", _obj_name );
		if (delta_ms> 3*dwUpdate)	{
			//Msg	("! xrSheduler: failed to shedule object [%s] (%dms)",	_obj_name, delta_ms	);
		}
//		if (execTime> 15)			{
//			Msg	("* xrSheduler: too much time consumed by object [%s] (%dms)",	_obj_name, execTime	);
//		}
#endif // DEBUG

		// 
		if ((i % 3) != (3 - 1))
			continue;

		if (Device.dwPrecacheFrame==0 && CPU::QPC() > cycles_limit)		
		{
			// we have maxed out the load - increase heap
			psShedulerTarget		+= (psShedulerReaction * 3);
			break;
		}
	}

	// Push "processed" back
	while (ItemsProcessed.size())	{
		Push	(ItemsProcessed.back())	;
		ItemsProcessed.pop_back		()	;
	}

	// always try to decrease target
	psShedulerTarget	-= psShedulerReaction;
}
示例#14
0
CRenderTarget::CRenderTarget		()
{
    u32 SampleCount = 1;

    if (ps_r_ssao_mode!=2/*hdao*/)
        ps_r_ssao = _min(ps_r_ssao, 3);

    if( RImplementation.o.dx10_msaa )
        SampleCount    = RImplementation.o.dx10_msaa_samples;

#ifdef DEBUG
    Msg			("MSAA samples = %d", SampleCount );
    if( RImplementation.o.dx10_msaa_opt )
        Msg		("dx10_MSAA_opt = on" );
    if( RImplementation.o.dx10_gbuffer_opt )
        Msg		("dx10_gbuffer_opt = on" );
#endif // DEBUG
    param_blur			= 0.f;
    param_gray			= 0.f;
    param_noise			= 0.f;
    param_duality_h		= 0.f;
    param_duality_v		= 0.f;
    param_noise_fps		= 25.f;
    param_noise_scale	= 1.f;

    im_noise_time		= 1/100;
    im_noise_shift_w	= 0;
    im_noise_shift_h	= 0;

    param_color_base	= color_rgba(127,127,127,	0);
    param_color_gray	= color_rgba(85,85,85,		0);
    //param_color_add		= color_rgba(0,0,0,			0);
    param_color_add.set( 0.0f, 0.0f, 0.0f );

    dwAccumulatorClearMark			= 0;
    dxRenderDeviceRender::Instance().Resources->Evict			();

    // Blenders
    b_occq					= xr_new<CBlender_light_occq>			();
    b_accum_mask			= xr_new<CBlender_accum_direct_mask>	();
    b_accum_direct			= xr_new<CBlender_accum_direct>			();
    b_accum_point			= xr_new<CBlender_accum_point>			();
    b_accum_spot			= xr_new<CBlender_accum_spot>			();
    b_accum_reflected		= xr_new<CBlender_accum_reflected>		();
    b_bloom					= xr_new<CBlender_bloom_build>			();
    if( RImplementation.o.dx10_msaa )
    {
        b_bloom_msaa			= xr_new<CBlender_bloom_build_msaa>		();
        b_postprocess_msaa	= xr_new<CBlender_postprocess_msaa>	();
    }
    b_luminance				= xr_new<CBlender_luminance>			();
    b_combine				= xr_new<CBlender_combine>				();
    b_ssao					= xr_new<CBlender_SSAO_noMSAA>			();

    if( RImplementation.o.dx10_msaa )
    {
        int bound = RImplementation.o.dx10_msaa_samples;

        if( RImplementation.o.dx10_msaa_opt )
            bound = 1;

        for( int i = 0; i < bound; ++i )
        {
            static LPCSTR SampleDefs[] = { "0","1","2","3","4","5","6","7" };
            b_combine_msaa[i]							= xr_new<CBlender_combine_msaa>					();
            b_accum_mask_msaa[i]						= xr_new<CBlender_accum_direct_mask_msaa>		();
            b_accum_direct_msaa[i]					= xr_new<CBlender_accum_direct_msaa>			();
            b_accum_direct_volumetric_msaa[i]			= xr_new<CBlender_accum_direct_volumetric_msaa>	();
            //b_accum_direct_volumetric_sun_msaa[i]	= xr_new<CBlender_accum_direct_volumetric_sun_msaa>			();
            b_accum_spot_msaa[i]		 				= xr_new<CBlender_accum_spot_msaa>			();
            b_accum_volumetric_msaa[i]				= xr_new<CBlender_accum_volumetric_msaa>	();
            b_accum_point_msaa[i]						= xr_new<CBlender_accum_point_msaa>			();
            b_accum_reflected_msaa[i]					= xr_new<CBlender_accum_reflected_msaa>		();
            b_ssao_msaa[i]							= xr_new<CBlender_SSAO_MSAA>				();
            static_cast<CBlender_accum_direct_mask_msaa*>( b_accum_mask_msaa[i] )->SetDefine( "ISAMPLE", SampleDefs[i]);
            static_cast<CBlender_accum_direct_volumetric_msaa*>(b_accum_direct_volumetric_msaa[i])->SetDefine( "ISAMPLE", SampleDefs[i]);
            //static_cast<CBlender_accum_direct_volumetric_sun_msaa*>(b_accum_direct_volumetric_sun_msaa[i])->SetDefine( "ISAMPLE", SampleDefs[i]);
            static_cast<CBlender_accum_direct_msaa*>(b_accum_direct_msaa[i])->SetDefine( "ISAMPLE", SampleDefs[i]);
            static_cast<CBlender_accum_volumetric_msaa*>(b_accum_volumetric_msaa[i])->SetDefine( "ISAMPLE", SampleDefs[i]);
            static_cast<CBlender_accum_spot_msaa*>(b_accum_spot_msaa[i])->SetDefine( "ISAMPLE", SampleDefs[i]);
            static_cast<CBlender_accum_point_msaa*>(b_accum_point_msaa[i])->SetDefine( "ISAMPLE", SampleDefs[i]);
            static_cast<CBlender_accum_reflected_msaa*>(b_accum_reflected_msaa[i])->SetDefine( "ISAMPLE", SampleDefs[i]);
            static_cast<CBlender_combine_msaa*>(b_combine_msaa[i])->SetDefine( "ISAMPLE", SampleDefs[i]);
            static_cast<CBlender_SSAO_MSAA*>(b_ssao_msaa[i])->SetDefine("ISAMPLE", SampleDefs[i]);
        }
    }
    //	NORMAL
    {
        u32		w=Device.dwWidth, h=Device.dwHeight;
        rt_Position.create			(r2_RT_P,		w,h,D3DFMT_A16B16G16R16F, SampleCount );

        if( RImplementation.o.dx10_msaa )
            rt_MSAADepth.create( r2_RT_MSAAdepth, w, h, D3DFMT_D24S8, SampleCount );

        if( !RImplementation.o.dx10_gbuffer_opt )
            rt_Normal.create			(r2_RT_N,		w,h,D3DFMT_A16B16G16R16F, SampleCount );

        // select albedo & accum
        if (RImplementation.o.mrtmixdepth)
        {
            // NV50
            rt_Color.create			(r2_RT_albedo,	w,h,D3DFMT_A8R8G8B8		, SampleCount );
            rt_Accumulator.create	(r2_RT_accum,	w,h,D3DFMT_A16B16G16R16F, SampleCount );
        }
        else
        {
            // can't - mix-depth
            if (RImplementation.o.fp16_blend) {
                // NV40
                if( !RImplementation.o.dx10_gbuffer_opt )
                {
                    rt_Color.create				(r2_RT_albedo,		w,h,D3DFMT_A16B16G16R16F, SampleCount );	// expand to full
                    rt_Accumulator.create		(r2_RT_accum,		w,h,D3DFMT_A16B16G16R16F, SampleCount );
                }
                else
                {
                    rt_Color.create				(r2_RT_albedo,		w,h,D3DFMT_A8R8G8B8,       SampleCount );	// expand to full
                    rt_Accumulator.create		(r2_RT_accum,		w,h,D3DFMT_A16B16G16R16F,  SampleCount );
                }
            } else {
                // R4xx, no-fp-blend,-> albedo_wo
                VERIFY						(RImplementation.o.albedo_wo);
                rt_Color.create				(r2_RT_albedo,		   w,h,D3DFMT_A8R8G8B8		, SampleCount );	// normal
                rt_Accumulator.create		(r2_RT_accum,		   w,h,D3DFMT_A16B16G16R16F, SampleCount );
                rt_Accumulator_temp.create	(r2_RT_accum_temp,	w,h,D3DFMT_A16B16G16R16F, SampleCount );
            }
        }

        // generic(LDR) RTs
        rt_Generic_0.create		(r2_RT_generic0,w,h,D3DFMT_A8R8G8B8, 1		);
        rt_Generic_1.create		(r2_RT_generic1,w,h,D3DFMT_A8R8G8B8, 1		);
        if( RImplementation.o.dx10_msaa )
        {
            rt_Generic_0_r.create(r2_RT_generic0_r,w,h,D3DFMT_A8R8G8B8, SampleCount	);
            rt_Generic_1_r.create(r2_RT_generic1_r,w,h,D3DFMT_A8R8G8B8, SampleCount		);
            rt_Generic.create	 (r2_RT_generic,w,h,   D3DFMT_A8R8G8B8, 1		);
        }
        //	Igor: for volumetric lights
        //rt_Generic_2.create			(r2_RT_generic2,w,h,D3DFMT_A8R8G8B8		);
        //	temp: for higher quality blends
        if (RImplementation.o.advancedpp)
            rt_Generic_2.create			(r2_RT_generic2,w,h,D3DFMT_A16B16G16R16F, SampleCount );
    }

    // OCCLUSION
    s_occq.create					(b_occq,		"r2\\occq");

    // DIRECT (spot)
    D3DFORMAT						depth_format	= (D3DFORMAT)RImplementation.o.HW_smap_FORMAT;

    if (RImplementation.o.HW_smap)
    {
        D3DFORMAT	nullrt				= D3DFMT_R5G6B5;
        if (RImplementation.o.nullrt)	nullrt	= (D3DFORMAT)MAKEFOURCC('N','U','L','L');

        u32	size					=RImplementation.o.smapsize	;
        rt_smap_depth.create		(r2_RT_smap_depth,			size,size,depth_format	);

        if (RImplementation.o.dx10_minmax_sm)
        {
            rt_smap_depth_minmax.create( r2_RT_smap_depth_minmax,	size/4,size/4, D3DFMT_R32F	);
            CBlender_createminmax TempBlender;
            s_create_minmax_sm.create( &TempBlender, "null" );
        }

        //rt_smap_surf.create			(r2_RT_smap_surf,			size,size,nullrt		);
        //rt_smap_ZB					= NULL;
        s_accum_mask.create			(b_accum_mask,				"r3\\accum_mask");
        s_accum_direct.create		(b_accum_direct,			"r3\\accum_direct");


        if( RImplementation.o.dx10_msaa )
        {
            int bound = RImplementation.o.dx10_msaa_samples;

            if( RImplementation.o.dx10_msaa_opt )
                bound = 1;

            for( int i = 0; i < bound; ++i )
            {
                s_accum_direct_msaa[i].create		(b_accum_direct_msaa[i],			"r3\\accum_direct");
                s_accum_mask_msaa[i].create		(b_accum_mask_msaa[i],			"r3\\accum_direct");
            }
        }
        if (RImplementation.o.advancedpp)
        {
            s_accum_direct_volumetric.create("accum_volumetric_sun_nomsaa");

            if (RImplementation.o.dx10_minmax_sm)
                s_accum_direct_volumetric_minmax.create("accum_volumetric_sun_nomsaa_minmax");

            if( RImplementation.o.dx10_msaa )
            {
                static LPCSTR snames[] = { "accum_volumetric_sun_msaa0",
                                           "accum_volumetric_sun_msaa1",
                                           "accum_volumetric_sun_msaa2",
                                           "accum_volumetric_sun_msaa3",
                                           "accum_volumetric_sun_msaa4",
                                           "accum_volumetric_sun_msaa5",
                                           "accum_volumetric_sun_msaa6",
                                           "accum_volumetric_sun_msaa7"
                                         };
                int bound = RImplementation.o.dx10_msaa_samples;

                if( RImplementation.o.dx10_msaa_opt )
                    bound = 1;

                for( int i = 0; i < bound; ++i )
                {
                    //s_accum_direct_volumetric_msaa[i].create		(b_accum_direct_volumetric_sun_msaa[i],			"r3\\accum_direct");
                    s_accum_direct_volumetric_msaa[i].create		(snames[i]);
                }
            }
        }
    }
    else
    {
        //	TODO: DX10: Check if we need old-style SMap
        VERIFY(!"Use HW SMAPs only!");
        //u32	size					=RImplementation.o.smapsize	;
        //rt_smap_surf.create			(r2_RT_smap_surf,			size,size,D3DFMT_R32F);
        //rt_smap_depth				= NULL;
        //R_CHK						(HW.pDevice->CreateDepthStencilSurface	(size,size,D3DFMT_D24X8,D3DMULTISAMPLE_NONE,0,TRUE,&rt_smap_ZB,NULL));
        //s_accum_mask.create			(b_accum_mask,				"r2\\accum_mask");
        //s_accum_direct.create		(b_accum_direct,			"r2\\accum_direct");
        //if (RImplementation.o.advancedpp)
        //	s_accum_direct_volumetric.create("accum_volumetric_sun");
    }

    //	RAIN
    //	TODO: DX10: Create resources only when DX10 rain is enabled.
    //	Or make DX10 rain switch dynamic?
    {
        CBlender_rain	TempBlender;
        s_rain.create( &TempBlender, "null");

        if( RImplementation.o.dx10_msaa )
        {
            static LPCSTR SampleDefs[] = { "0","1","2","3","4","5","6","7" };
            CBlender_rain_msaa	TempBlender[8];

            int bound = RImplementation.o.dx10_msaa_samples;

            if( RImplementation.o.dx10_msaa_opt )
                bound = 1;

            for( int i = 0; i < bound; ++i )
            {
                TempBlender[i].SetDefine( "ISAMPLE", SampleDefs[i] );
                s_rain_msaa[i].create( &TempBlender[i], "null");
                s_accum_spot_msaa[i].create			(b_accum_spot_msaa[i],				"r2\\accum_spot_s",	"lights\\lights_spot01");
                s_accum_point_msaa[i].create		(b_accum_point_msaa[i],			"r2\\accum_point_s");
                //s_accum_volume_msaa[i].create(b_accum_direct_volumetric_msaa[i], "lights\\lights_spot01");
                s_accum_volume_msaa[i].create(b_accum_volumetric_msaa[i], "lights\\lights_spot01");
                s_combine_msaa[i].create					(b_combine_msaa[i],					"r2\\combine");
            }
        }
    }

    if( RImplementation.o.dx10_msaa )
    {
        CBlender_msaa TempBlender;

        s_mark_msaa_edges.create( &TempBlender, "null" );
    }

    // POINT
    {
        s_accum_point.create		(b_accum_point,				"r2\\accum_point_s");
        accum_point_geom_create		();
        g_accum_point.create		(D3DFVF_XYZ,				g_accum_point_vb, g_accum_point_ib);
        accum_omnip_geom_create		();
        g_accum_omnipart.create		(D3DFVF_XYZ,				g_accum_omnip_vb, g_accum_omnip_ib);
    }

    // SPOT
    {
        s_accum_spot.create			(b_accum_spot,				"r2\\accum_spot_s",	"lights\\lights_spot01");
        accum_spot_geom_create		();
        g_accum_spot.create			(D3DFVF_XYZ,				g_accum_spot_vb, g_accum_spot_ib);
    }

    {
        s_accum_volume.create("accum_volumetric", "lights\\lights_spot01");
        accum_volumetric_geom_create();
        g_accum_volumetric.create( D3DFVF_XYZ, g_accum_volumetric_vb, g_accum_volumetric_ib);
    }


    // REFLECTED
    {
        s_accum_reflected.create	(b_accum_reflected,			"r2\\accum_refl");
        if( RImplementation.o.dx10_msaa )
        {
            int bound = RImplementation.o.dx10_msaa_samples;

            if( RImplementation.o.dx10_msaa_opt )
                bound = 1;

            for( int i = 0; i < bound; ++i )
            {
                s_accum_reflected_msaa[i].create( b_accum_reflected_msaa[i], "null");
            }
        }
    }

    // BLOOM
    {
        D3DFORMAT	fmt				= D3DFMT_A8R8G8B8;			//;		// D3DFMT_X8R8G8B8
        u32	w=BLOOM_size_X, h=BLOOM_size_Y;
        u32 fvf_build				= D3DFVF_XYZRHW|D3DFVF_TEX4|D3DFVF_TEXCOORDSIZE2(0)|D3DFVF_TEXCOORDSIZE2(1)|D3DFVF_TEXCOORDSIZE2(2)|D3DFVF_TEXCOORDSIZE2(3);
        u32 fvf_filter				= (u32)D3DFVF_XYZRHW|D3DFVF_TEX8|D3DFVF_TEXCOORDSIZE4(0)|D3DFVF_TEXCOORDSIZE4(1)|D3DFVF_TEXCOORDSIZE4(2)|D3DFVF_TEXCOORDSIZE4(3)|D3DFVF_TEXCOORDSIZE4(4)|D3DFVF_TEXCOORDSIZE4(5)|D3DFVF_TEXCOORDSIZE4(6)|D3DFVF_TEXCOORDSIZE4(7);
        rt_Bloom_1.create			(r2_RT_bloom1,	w,h,		fmt);
        rt_Bloom_2.create			(r2_RT_bloom2,	w,h,		fmt);
        g_bloom_build.create		(fvf_build,		RCache.Vertex.Buffer(), RCache.QuadIB);
        g_bloom_filter.create		(fvf_filter,	RCache.Vertex.Buffer(), RCache.QuadIB);
        s_bloom_dbg_1.create		("effects\\screen_set",		r2_RT_bloom1);
        s_bloom_dbg_2.create		("effects\\screen_set",		r2_RT_bloom2);
        s_bloom.create				(b_bloom,					"r2\\bloom");
        if( RImplementation.o.dx10_msaa )
        {
            s_bloom_msaa.create		 (b_bloom_msaa,					"r2\\bloom");
            s_postprocess_msaa.create(b_postprocess_msaa,			"r2\\post");
        }
        f_bloom_factor				= 0.5f;
    }

    // TONEMAP
    {
        rt_LUM_64.create			(r2_RT_luminance_t64,	64, 64,	D3DFMT_A16B16G16R16F	);
        rt_LUM_8.create				(r2_RT_luminance_t8,	8,	8,	D3DFMT_A16B16G16R16F	);
        s_luminance.create			(b_luminance,				"r2\\luminance");
        f_luminance_adapt			= 0.5f;

        t_LUM_src.create			(r2_RT_luminance_src);
        t_LUM_dest.create			(r2_RT_luminance_cur);

        // create pool
        for (u32 it=0; it<HW.Caps.iGPUNum*2; it++)	{
            string256					name;
            xr_sprintf						(name,"%s_%d",	r2_RT_luminance_pool,it	);
            rt_LUM_pool[it].create		(name,	1,	1,	D3DFMT_R32F				);
            //u_setrt						(rt_LUM_pool[it],	0,	0,	0			);
            //CHK_DX						(HW.pDevice->Clear( 0L, NULL, D3DCLEAR_TARGET,	0x7f7f7f7f,	1.0f, 0L));
            FLOAT ColorRGBA[4] = { 127.0f/255.0f, 127.0f/255.0f, 127.0f/255.0f, 127.0f/255.0f};
            HW.pDevice->ClearRenderTargetView(rt_LUM_pool[it]->pRT, ColorRGBA);
        }
        u_setrt						( Device.dwWidth,Device.dwHeight,HW.pBaseRT,NULL,NULL,HW.pBaseZB);
    }

    // HBAO
    if (RImplementation.o.ssao_opt_data)
    {
        u32		w = 0;
        u32		h = 0;
        if (RImplementation.o.ssao_half_data)
        {
            w = Device.dwWidth / 2;
            h = Device.dwHeight / 2;
        }
        else
        {
            w = Device.dwWidth;
            h = Device.dwHeight;
        }

        D3DFORMAT	fmt = HW.Caps.id_vendor==0x10DE?D3DFMT_R32F:D3DFMT_R16F;
        rt_half_depth.create		(r2_RT_half_depth, w, h, fmt);

        s_ssao.create				(b_ssao, "r2\\ssao");
    }

    if (RImplementation.o.ssao_blur_on)
    {
        u32		w = Device.dwWidth, h = Device.dwHeight;
        rt_ssao_temp.create			(r2_RT_ssao_temp, w, h, D3DFMT_G16R16F, SampleCount);
        s_ssao.create				(b_ssao, "r2\\ssao");

        if( RImplementation.o.dx10_msaa )
        {
            int bound = RImplementation.o.dx10_msaa_opt ? 1 : RImplementation.o.dx10_msaa_samples;

            for( int i = 0; i < bound; ++i )
            {
                s_ssao_msaa[i].create( b_ssao_msaa[i], "null");
            }
        }
    }

    // COMBINE
    {
        static D3DVERTEXELEMENT9 dwDecl[] =
        {
            { 0, 0,  D3DDECLTYPE_FLOAT4,	D3DDECLMETHOD_DEFAULT, 	D3DDECLUSAGE_POSITION,	0 },	// pos+uv
            D3DDECL_END()
        };
        s_combine.create					(b_combine,					"r2\\combine");
        s_combine_volumetric.create			("combine_volumetric");
        s_combine_dbg_0.create				("effects\\screen_set",		r2_RT_smap_surf		);
        s_combine_dbg_1.create				("effects\\screen_set",		r2_RT_luminance_t8	);
        s_combine_dbg_Accumulator.create	("effects\\screen_set",		r2_RT_accum			);
        g_combine_VP.create					(dwDecl,		RCache.Vertex.Buffer(), RCache.QuadIB);
        g_combine.create					(FVF::F_TL,		RCache.Vertex.Buffer(), RCache.QuadIB);
        g_combine_2UV.create				(FVF::F_TL2uv,	RCache.Vertex.Buffer(), RCache.QuadIB);
        g_combine_cuboid.create				(dwDecl,	RCache.Vertex.Buffer(), RCache.Index.Buffer());

        u32 fvf_aa_blur				= D3DFVF_XYZRHW|D3DFVF_TEX4|D3DFVF_TEXCOORDSIZE2(0)|D3DFVF_TEXCOORDSIZE2(1)|D3DFVF_TEXCOORDSIZE2(2)|D3DFVF_TEXCOORDSIZE2(3);
        g_aa_blur.create			(fvf_aa_blur,	RCache.Vertex.Buffer(), RCache.QuadIB);

        u32 fvf_aa_AA				= D3DFVF_XYZRHW|D3DFVF_TEX7|D3DFVF_TEXCOORDSIZE2(0)|D3DFVF_TEXCOORDSIZE2(1)|D3DFVF_TEXCOORDSIZE2(2)|D3DFVF_TEXCOORDSIZE2(3)|D3DFVF_TEXCOORDSIZE2(4)|D3DFVF_TEXCOORDSIZE4(5)|D3DFVF_TEXCOORDSIZE4(6);
        g_aa_AA.create				(fvf_aa_AA,		RCache.Vertex.Buffer(), RCache.QuadIB);

        t_envmap_0.create			(r2_T_envs0);
        t_envmap_1.create			(r2_T_envs1);
    }

    // Build textures
    {
        // Testure for async sreenshots
        {
            D3D10_TEXTURE2D_DESC	desc;
            desc.Width = Device.dwWidth;
            desc.Height = Device.dwHeight;
            desc.MipLevels = 1;
            desc.ArraySize = 1;
            desc.SampleDesc.Count = 1;
            desc.SampleDesc.Quality = 0;
            desc.Format = DXGI_FORMAT_R8G8B8A8_SNORM;
            desc.Usage = D3D10_USAGE_STAGING;
            desc.BindFlags = 0;
            desc.CPUAccessFlags = D3D10_CPU_ACCESS_READ;
            desc.MiscFlags = 0;

            R_CHK( HW.pDevice->CreateTexture2D(&desc, 0, &t_ss_async) );
        }
        // Build material(s)
        {
            //	Create immutable texture.
            //	So we need to init data _before_ the creation.
            // Surface
            //R_CHK						(D3DXCreateVolumeTexture(HW.pDevice,TEX_material_LdotN,TEX_material_LdotH,4,1,0,D3DFMT_A8L8,D3DPOOL_MANAGED,&t_material_surf));
            //t_material					= dxRenderDeviceRender::Instance().Resources->_CreateTexture(r2_material);
            //t_material->surface_set		(t_material_surf);
            //	Use DXGI_FORMAT_R8G8_UNORM

            u16	tempData[TEX_material_LdotN*TEX_material_LdotH*TEX_material_Count];

            D3D10_TEXTURE3D_DESC	desc;
            desc.Width = TEX_material_LdotN;
            desc.Height = TEX_material_LdotH;
            desc.Depth	= TEX_material_Count;
            desc.MipLevels = 1;
            desc.Format = DXGI_FORMAT_R8G8_UNORM;
            desc.Usage = D3D10_USAGE_IMMUTABLE;
            desc.BindFlags = D3D10_BIND_SHADER_RESOURCE;
            desc.CPUAccessFlags = 0;
            desc.MiscFlags = 0;

            D3D10_SUBRESOURCE_DATA	subData;

            subData.pSysMem = tempData;
            subData.SysMemPitch = desc.Width*2;
            subData.SysMemSlicePitch = desc.Height*subData.SysMemPitch;

            // Fill it (addr: x=dot(L,N),y=dot(L,H))
            //D3DLOCKED_BOX				R;
            //R_CHK						(t_material_surf->LockBox	(0,&R,0,0));
            for (u32 slice=0; slice<TEX_material_Count; slice++)
            {
                for (u32 y=0; y<TEX_material_LdotH; y++)
                {
                    for (u32 x=0; x<TEX_material_LdotN; x++)
                    {
                        u16*	p	=	(u16*)
                                        (LPBYTE (subData.pSysMem)
                                         + slice*subData.SysMemSlicePitch
                                         + y*subData.SysMemPitch + x*2);
                        float	ld	=	float(x)	/ float	(TEX_material_LdotN-1);
                        float	ls	=	float(y)	/ float	(TEX_material_LdotH-1) + EPS_S;
                        ls			*=	powf(ld,1/32.f);
                        float	fd,fs;

                        switch	(slice)
                        {
                        case 0:	{ // looks like OrenNayar
                            fd	= powf(ld,0.75f);		// 0.75
                            fs	= powf(ls,16.f)*.5f;
                        }
                        break;
                        case 1:	{// looks like Blinn
                            fd	= powf(ld,0.90f);		// 0.90
                            fs	= powf(ls,24.f);
                        }
                        break;
                        case 2:	{ // looks like Phong
                            fd	= ld;					// 1.0
                            fs	= powf(ls*1.01f,128.f	);
                        }
                        break;
                        case 3:	{ // looks like Metal
                            float	s0	=	_abs	(1-_abs	(0.05f*_sin(33.f*ld)+ld-ls));
                            float	s1	=	_abs	(1-_abs	(0.05f*_cos(33.f*ld*ls)+ld-ls));
                            float	s2	=	_abs	(1-_abs	(ld-ls));
                            fd		=	ld;				// 1.0
                            fs		=	powf	(_max(_max(s0,s1),s2), 24.f);
                            fs		*=	powf	(ld,1/7.f);
                        }
                        break;
                        default:
                            fd	= fs = 0;
                        }
                        s32		_d	=	clampr	(iFloor	(fd*255.5f),	0,255);
                        s32		_s	=	clampr	(iFloor	(fs*255.5f),	0,255);
                        if ((y==(TEX_material_LdotH-1)) && (x==(TEX_material_LdotN-1)))	{
                            _d = 255;
                            _s=255;
                        }
                        *p			=	u16		(_s*256 + _d);
                    }
                }
            }
            //R_CHK		(t_material_surf->UnlockBox	(0));

            R_CHK(HW.pDevice->CreateTexture3D(&desc, &subData, &t_material_surf));
            t_material					= dxRenderDeviceRender::Instance().Resources->_CreateTexture(r2_material);
            t_material->surface_set		(t_material_surf);
            //R_CHK						(D3DXCreateVolumeTexture(HW.pDevice,TEX_material_LdotN,TEX_material_LdotH,4,1,0,D3DFMT_A8L8,D3DPOOL_MANAGED,&t_material_surf));
            //t_material					= dxRenderDeviceRender::Instance().Resources->_CreateTexture(r2_material);
            //t_material->surface_set		(t_material_surf);

            // #ifdef DEBUG
            // R_CHK	(D3DXSaveTextureToFile	("x:\\r2_material.dds",D3DXIFF_DDS,t_material_surf,0));
            // #endif
        }

        // Build noise table
        if (1)
        {
            // Surfaces
            //D3DLOCKED_RECT				R[TEX_jitter_count];

            //for (int it=0; it<TEX_jitter_count; it++)
            //{
            //	string_path					name;
            //	xr_sprintf						(name,"%s%d",r2_jitter,it);
            //	R_CHK	(D3DXCreateTexture	(HW.pDevice,TEX_jitter,TEX_jitter,1,0,D3DFMT_Q8W8V8U8,D3DPOOL_MANAGED,&t_noise_surf[it]));
            //	t_noise[it]					= dxRenderDeviceRender::Instance().Resources->_CreateTexture	(name);
            //	t_noise[it]->surface_set	(t_noise_surf[it]);
            //	R_CHK						(t_noise_surf[it]->LockRect	(0,&R[it],0,0));
            //}
            //	Use DXGI_FORMAT_R8G8B8A8_SNORM

            static const int sampleSize = 4;
            u32	tempData[TEX_jitter_count][TEX_jitter*TEX_jitter];

            D3D10_TEXTURE2D_DESC	desc;
            desc.Width = TEX_jitter;
            desc.Height = TEX_jitter;
            desc.MipLevels = 1;
            desc.ArraySize = 1;
            desc.SampleDesc.Count = 1;
            desc.SampleDesc.Quality = 0;
            desc.Format = DXGI_FORMAT_R8G8B8A8_SNORM;
            //desc.Usage = D3D10_USAGE_IMMUTABLE;
            desc.Usage = D3D10_USAGE_DEFAULT;
            desc.BindFlags = D3D10_BIND_SHADER_RESOURCE;
            desc.CPUAccessFlags = 0;
            desc.MiscFlags = 0;

            D3D10_SUBRESOURCE_DATA	subData[TEX_jitter_count];

            for (int it=0; it<TEX_jitter_count-1; it++)
            {
                subData[it].pSysMem = tempData[it];
                subData[it].SysMemPitch = desc.Width*sampleSize;
            }

            // Fill it,
            for (u32 y=0; y<TEX_jitter; y++)
            {
                for (u32 x=0; x<TEX_jitter; x++)
                {
                    DWORD	data	[TEX_jitter_count-1];
                    generate_jitter	(data,TEX_jitter_count-1);
                    for (u32 it=0; it<TEX_jitter_count-1; it++)
                    {
                        u32*	p	=	(u32*)
                                        (LPBYTE (subData[it].pSysMem)
                                         + y*subData[it].SysMemPitch
                                         + x*4);

                        *p	=	data	[it];
                    }
                }
            }

            //for (int it=0; it<TEX_jitter_count; it++)	{
            //	R_CHK						(t_noise_surf[it]->UnlockRect(0));
            //}

            for (int it=0; it<TEX_jitter_count-1; it++)
            {
                string_path					name;
                xr_sprintf						(name,"%s%d",r2_jitter,it);
                //R_CHK	(D3DXCreateTexture	(HW.pDevice,TEX_jitter,TEX_jitter,1,0,D3DFMT_Q8W8V8U8,D3DPOOL_MANAGED,&t_noise_surf[it]));
                R_CHK( HW.pDevice->CreateTexture2D(&desc, &subData[it], &t_noise_surf[it]) );
                t_noise[it]					= dxRenderDeviceRender::Instance().Resources->_CreateTexture	(name);
                t_noise[it]->surface_set	(t_noise_surf[it]);
                //R_CHK						(t_noise_surf[it]->LockRect	(0,&R[it],0,0));
            }

            float tempDataHBAO[TEX_jitter*TEX_jitter*4];

            // generate HBAO jitter texture (last)
            D3D10_TEXTURE2D_DESC	descHBAO;
            descHBAO.Width = TEX_jitter;
            descHBAO.Height = TEX_jitter;
            descHBAO.MipLevels = 1;
            descHBAO.ArraySize = 1;
            descHBAO.SampleDesc.Count = 1;
            descHBAO.SampleDesc.Quality = 0;
            descHBAO.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
            //desc.Usage = D3D10_USAGE_IMMUTABLE;
            descHBAO.Usage = D3D10_USAGE_DEFAULT;
            descHBAO.BindFlags = D3D10_BIND_SHADER_RESOURCE;
            descHBAO.CPUAccessFlags = 0;
            descHBAO.MiscFlags = 0;

            it = TEX_jitter_count-1;
            subData[it].pSysMem = tempDataHBAO;
            subData[it].SysMemPitch = descHBAO.Width*sampleSize * sizeof(float);

            // Fill it,
            for (u32 y=0; y<TEX_jitter; y++)
            {
                for (u32 x=0; x<TEX_jitter; x++)
                {
                    float numDir = 1.0f;
                    switch (ps_r_ssao)
                    {
                    case 1:
                        numDir = 4.0f;
                        break;
                    case 2:
                        numDir = 6.0f;
                        break;
                    case 3:
                        numDir = 8.0f;
                        break;
                    case 4:
                        numDir = 8.0f;
                        break;
                    }
                    float angle = 2 * PI * ::Random.randF(0.0f, 1.0f) / numDir;
                    float dist = ::Random.randF(0.0f, 1.0f);

                    float *p	=	(float*)
                                    (LPBYTE (subData[it].pSysMem)
                                     + y*subData[it].SysMemPitch
                                     + x*4*sizeof(float));
                    *p = (float)(_cos(angle));
                    *(p+1) = (float)(_sin(angle));
                    *(p+2) = (float)(dist);
                    *(p+3) = 0;
                }
            }

            string_path					name;
            xr_sprintf						(name,"%s%d",r2_jitter,it);
            //R_CHK	(D3DXCreateTexture	(HW.pDevice,TEX_jitter,TEX_jitter,1,0,D3DFMT_Q8W8V8U8,D3DPOOL_MANAGED,&t_noise_surf[it]));
            R_CHK( HW.pDevice->CreateTexture2D(&descHBAO, &subData[it], &t_noise_surf[it]) );
            t_noise[it]					= dxRenderDeviceRender::Instance().Resources->_CreateTexture	(name);
            t_noise[it]->surface_set	(t_noise_surf[it]);


            //	Create noise mipped
            {
                //	Autogen mipmaps
                desc.MipLevels = 0;
                R_CHK( HW.pDevice->CreateTexture2D(&desc, 0, &t_noise_surf_mipped) );
                t_noise_mipped = dxRenderDeviceRender::Instance().Resources->_CreateTexture(r2_jitter_mipped);
                t_noise_mipped->surface_set(t_noise_surf_mipped);

                //	Update texture. Generate mips.

                HW.pDevice->CopySubresourceRegion( t_noise_surf_mipped, 0, 0, 0, 0, t_noise_surf[0], 0, 0 );

                D3DX10FilterTexture(t_noise_surf_mipped, 0, D3DX10_FILTER_POINT);
            }
        }
    }

    // PP
    s_postprocess.create				("postprocess");
    g_postprocess.create				(D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_SPECULAR|D3DFVF_TEX3,RCache.Vertex.Buffer(),RCache.QuadIB);

    // Menu
    s_menu.create						("distort");
    g_menu.create						(FVF::F_TL,RCache.Vertex.Buffer(),RCache.QuadIB);

    //
    dwWidth		= Device.dwWidth;
    dwHeight	= Device.dwHeight;
}
void CLight_Compute_XFORM_and_VIS::compute_xf_spot	(light* L)
{
	// Build EYE-space xform
	Fvector						L_dir,L_up,L_right,L_pos;
	L_dir.set					(L->direction);			L_dir.normalize		();

	if (L->right.square_magnitude()>EPS)				{
		// use specified 'up' and 'right', just enshure ortho-normalization
		L_right.set					(L->right);				L_right.normalize	();
		L_up.crossproduct			(L_dir,L_right);		L_up.normalize		();
		L_right.crossproduct		(L_up,L_dir);			L_right.normalize	();
	} else {
		// auto find 'up' and 'right' vectors
		L_up.set					(0,1,0);				if (_abs(L_up.dotproduct(L_dir))>.99f)	L_up.set(0,0,1);
		L_right.crossproduct		(L_up,L_dir);			L_right.normalize	();
		L_up.crossproduct			(L_dir,L_right);		L_up.normalize		();
	}
	L_pos.set						(L->position);
	
	// 
	int _cached_size			= L->X.S.size;
	L->X.S.posX	= L->X.S.posY	= 0;
	L->X.S.size					= SMAP_adapt_max;
	L->X.S.transluent			= FALSE;

	// Compute approximate screen area (treating it as an point light) - R*R/dist_sq
	// Note: we clamp screen space area to ONE, although it is not correct at all
	float	dist				= Device.vCameraPosition.distance_to(L->spatial.sphere.P)-L->spatial.sphere.R;
			if (dist<0)	dist	= 0;
	float	ssa					= clampr	(L->range*L->range / (1.f+dist*dist),0.f,1.f);

	// compute intensity
	float	intensity0			= (L->color.r + L->color.g + L->color.b)/3.f;
	float	intensity1			= (L->color.r * 0.2125f + L->color.g * 0.7154f + L->color.b * 0.0721f);
	float	intensity			= (intensity0+intensity1)/2.f;		// intensity1 tends to underestimate...

	// compute how much duelling frusta occurs	[-1..1]-> 1 + [-0.5 .. +0.5]
	float	duel_dot			= 1.f -	0.5f*Device.vCameraDirection.dotproduct(L_dir);

	// compute how large the light is - give more texels to larger lights, assume 8m as being optimal radius
	float	sizefactor			= L->range/8.f;				// 4m = .5, 8m=1.f, 16m=2.f, 32m=4.f

	// compute how wide the light frustum is - assume 90deg as being optimal
	float	widefactor			= L->cone/deg2rad(90.f);	// 

	// factors
	float	factor0				= powf	(ssa,		1.f/2.f);		// ssa is quadratic
	float	factor1				= powf	(intensity, 1.f/16.f);		// less perceptually important?
	float	factor2				= powf	(duel_dot,	1.f/4.f);		// difficult to fast-change this -> visible
	float	factor3				= powf	(sizefactor,1.f/4.f);		// this shouldn't make much difference
	float	factor4				= powf	(widefactor,1.f/2.f);		// make it linear ???
	float	factor				= ps_r2_ls_squality * factor0 * factor1 * factor2 * factor3 * factor4;
	
	// final size calc
	u32 _size					= iFloor( factor * SMAP_adapt_optimal );
	if (_size<SMAP_adapt_min)	_size	= SMAP_adapt_min;
	if (_size>SMAP_adapt_max)	_size	= SMAP_adapt_max;
	int _epsilon				= iCeil	(float(_size)*0.01f);
	int _diff					= _abs	(int(_size)-int(_cached_size));
	L->X.S.size					= (_diff>=_epsilon)?_size:_cached_size;

	// make N pixel border
	L->X.S.view.build_camera_dir	(L_pos,L_dir,L_up);
	//float	n			= 2.f						;
	//float	x			= float(L->X.S.size)		;
	//float	alpha		= L->cone/2					;
	//float	tan_beta	= (x+2*n)*tanf(alpha) / x	;
	//float	g_alpha		= 2*rad2deg		(alpha);
	//float	g_beta		= 2*rad2deg		(atanf(tan_beta));
	//Msg				("x(%f) : a(%f), b(%f)",x,g_alpha,g_beta);
	/************************************************** added by Ray Twitty (aka Shadows) START **************************************************/
	// только для поинта меняем на 11.5
	float				tan_shift;
	if (L->flags.type == IRender_Light::POINT)
		tan_shift		= deg2rad(11.5f);
	else
		tan_shift		= deg2rad(3.5f);
	/*************************************************** added by Ray Twitty (aka Shadows) END ***************************************************/
	L->X.S.project.build_projection		(L->cone + tan_shift, 1.f,/*SMAP_near_plane*/L->virtual_size,L->range+EPS_S);
	L->X.S.combine.mul					(L->X.S.project,L->X.S.view);
}
示例#16
0
IC void Dequantize(CKey& K,const CBlend& BD,const CMotion& M)
{
	CKey*			D		=	&K;
	const CBlend*	B		=	&BD;
	float			time	=	B->timeCurrent*float(SAMPLE_FPS);

	u32				frame	=	iFloor(time);
	float			delta	=	time-float(frame);
	u32				count	=	M.get_count();
	// rotation
	if (M.test_flag(flRKeyAbsent)){
		const CKeyQR *		K		=	&M._keysR[0];
		QR2Quat(*K,D->Q);
	}else{
		const CKeyQR*		K1r		=	&M._keysR[(frame+0)%count];
		const CKeyQR*		K2r		=	&M._keysR[(frame+1)%count];
		Fquaternion	Q1,Q2;
		QR2Quat(*K1r,Q1);
		QR2Quat(*K2r,Q2);
		D->Q.slerp	(Q1,Q2,clampr(delta,0.f,1.f));
	}

	// translate
	if (M.test_flag(flTKeyPresent))
	{
		const CKeyQT*	K1t	= &M._keysT[(frame+0)%count];
		const CKeyQT*	K2t	= &M._keysT[(frame+1)%count];

		Fvector T1,T2;
		QT2T(*K1t,M,T1);
		QT2T(*K2t,M,T2);
		/*
		T1.x		= float(K1t->x)*M._sizeT.x+M._initT.x;
		T1.y		= float(K1t->y)*M._sizeT.y+M._initT.y;
		T1.z		= float(K1t->z)*M._sizeT.z+M._initT.z;

		T2.x		= float(K2t->x)*M._sizeT.x+M._initT.x;
		T2.y		= float(K2t->y)*M._sizeT.y+M._initT.y;
		T2.z		= float(K2t->z)*M._sizeT.z+M._initT.z;
		*/
		D->T.lerp	(T1,T2,delta);
		/*					
		if ((_abs(D->T.y)>10000) || (_abs(D->T.x)>10000) || (_abs(D->T.z)>10000))
		{
		Log("xxx");
		Log("Blend--------");
		Log("blendAmount", B->blendAmount);
		Log("timeCurrent", B->timeCurrent);
		Log("timeTotal", B->timeTotal);
		Log("bone_or_part", B->bone_or_part);

		Log("blendAccrue", B->blendAccrue);
		Log("blendFalloff", B->blendFalloff);
		Log("blendPower", B->blendPower);
		Log("speed", B->speed);
		Log("playing", B->playing);
		Log("stop_at_end", B->stop_at_end);
		Log("motionID", (u32)B->motionID.idx);
		Log("blend", B->blend);

		Log("dwFrame", B->dwFrame);
		Log("Device.dwFrame", Device.dwFrame);
		Log("Blend-------end");

		Log("Bone",LL_BoneName_dbg(SelfID));
		Log("parent",*parent);
		Msg("K1t %d,%d,%d",K1t->x,K1t->y,K1t->z);
		Msg("K2t %d,%d,%d",K2t->x,K2t->y,K2t->z);

		Log("count",count);
		Log("time",time);
		Log("frame",frame);
		Log("T1",T1);
		Log("T2",T2);
		Log("delta",delta);
		Log("Dt",D->T);
		VERIFY(0);

		}
		*/
	} //if (M.test_flag(flTKeyPresent))
	else
	{
		D->T.set	(M._initT);
	}
}
示例#17
0
IC void MixInterlerp( CKey &Result, const CKey	*R, const float* BA, int b_count )
{

	VERIFY(MAX_BLENDED>=b_count);
	switch (b_count)
	{
	case 0:
		Result.Q.set	(0,0,0,0);
		Result.T.set	(0,0,0);
		break;
	case 1: 
		Result			= R[0];
		/*
		if(Result.T.y>10000){
		Log("1");
		Log("BLEND_INST",BLEND_INST.Blend.size());
		Log("Bone",LL_BoneName_dbg(SelfID));
		Msg("Result.Q %f,%f,%f,%f",Result.Q.x,Result.Q.y,Result.Q.z,Result.Q.w);
		Log("Result.T",Result.T);
		VERIFY(0);
		}
		*/
		break;
	case 2:
		{
			float w0 = BA[0];
			float w1 = BA[1];
			float ws = w0+w1;
			float w;
			if (fis_zero(ws))	w = 0;
			else				w = w1/ws;
#ifdef DEBUG
			//.					if (fis_zero(w0+w1) || (!_valid(w))){
			//.						Debug.fatal		(DEBUG_INFO,"TO ALEXMX VERY IMPORTANT: (TOTAL: %f) w: %f, w0: %f, w1: %f, ws:%f, BIS: %d",w0+w1,w,w0,w1,ws,BLEND_INST.Blend.size());
			//.					}
#endif
			KEY_Interp	(Result,R[0],R[1], clampr(w,0.f,1.f));
			/*
			if(Result.T.y>10000){
			Log("2");
			Log("BLEND_INST",BLEND_INST.Blend.size());
			Log("Bone",LL_BoneName_dbg(SelfID));
			Msg("Result.Q %f,%f,%f,%f",Result.Q.x,Result.Q.y,Result.Q.z,Result.Q.w);
			Log("Result.T",Result.T);
			Log("parent",*parent);
			VERIFY(0);
			}
			*/
		}
		break;
	default:
		{
			//int 	count 	= Blend.size();
			float   total 	= 0;
			ConsistantKey		S[MAX_BLENDED];
			for (int i=0; i<b_count; i++)					
				S[i].set	(R+i,BA[i]);

			std::sort	(S,S+b_count);
			CKey		tmp;
			total		= S[0].w;
			tmp			= *S[0].K;
			for 		(int cnt=1; cnt<b_count; cnt++){
				total	+= S[cnt].w;
				float	d;
				if (fis_zero(total))	d = 0.0f;
				else d	= S[cnt].w/total;

				clampr(d,0.f,1.f);

#ifdef DEBUG
				//.						if ((total==0) || (!_valid(S[cnt].w/total))){
				//.							Debug.fatal		(DEBUG_INFO,"TO ALEXMX VERY IMPORTANT: (TOTAL: %f) w: %f, total: %f, count: %d, real count: %d",total,S[cnt].w,total,count,BLEND_INST.Blend.size());
				//.						}
#endif

				KEY_Interp	(Result,tmp, *S[cnt].K, d );
				tmp 		= Result;
			}
		}
		break;
	}
}
示例#18
0
void	CROS_impl::update	(IRenderable* O)
{
	// clip & verify
	if					(dwFrame==Device.dwFrame)			return;
	dwFrame				= Device.dwFrame;
	if					(0==O)								return;
	if					(0==O->renderable.visual)			return;
	VERIFY				(dynamic_cast<CROS_impl*>			(O->renderable_ROS()));
	float	dt			=	Device.fTimeDelta;

	CObject*	_object	= dynamic_cast<CObject*>	(O);

	// select sample, randomize position inside object
	Fvector	position;	O->renderable.xform.transform_tiny	(position,O->renderable.visual->vis.sphere.P);
	float	radius;		radius	= O->renderable.visual->vis.sphere.R;
	position.y			+=  .3f * radius;
	Fvector	direction;	direction.random_dir();
//.			position.mad(direction,0.25f*radius);
//.			position.mad(direction,0.025f*radius);

	// sun-tracing
#if RENDER==R_R1
	light*	sun		=		(light*)RImplementation.L_DB->sun_adapted._get()	;
#else
	light*	sun		=		(light*)RImplementation.Lights.sun_adapted._get()	;
#endif
	if	(MODE & IRender_ObjectSpecific::TRACE_SUN)	{
		if  (--result_sun	< 0)	{
			result_sun		+=		::Random.randI(lt_hemisamples/4,lt_hemisamples/2)	;
			Fvector	direction;	direction.set	(sun->direction).invert().normalize	();
			sun_value		=	!(g_pGameLevel->ObjectSpace.RayTest(position,direction,500.f,collide::rqtBoth,&cache_sun,_object))?1.f:0.f;
		}
	}
	
	// hemi-tracing
	bool	bFirstTime	=	(0==result_count);
	if	(MODE & IRender_ObjectSpecific::TRACE_HEMI)	{
		for (u32 it=0; it<(u32)ps_r2_dhemi_count;	it++)		{	// five samples per one frame
			u32	sample		=	0				;
			if	(result_count<lt_hemisamples)	{ sample=result_count; result_count++;							}
			else								{ sample=(result_iterator%lt_hemisamples); result_iterator++;	}

			// take sample
			Fvector	direction;	direction.set	(hdir[sample][0],hdir[sample][1],hdir[sample][2]).normalize	();
//.			result[sample]	=	!g_pGameLevel->ObjectSpace.RayTest(position,direction,50.f,collide::rqtBoth,&cache[sample],_object);
			result[sample]	=	!g_pGameLevel->ObjectSpace.RayTest(position,direction,50.f,collide::rqtStatic,&cache[sample],_object);
			//	Msg				("%d:-- %s",sample,result[sample]?"true":"false");
		}
	}

	// hemi & sun: update and smooth
//	float	l_f				=	dt*lt_smooth;
//	float	l_i				=	1.f-l_f;
	int		_pass			=	0;
	for (int it=0; it<result_count; it++)	if (result[it])	_pass	++;
	hemi_value				=	float	(_pass)/float(result_count?result_count:1);
	hemi_value				*=	ps_r2_dhemi_scale;
	if (bFirstTime)			hemi_smooth		= hemi_value;
	update_smooth			()	;

	// light-tracing
	BOOL	bTraceLights	= MODE & IRender_ObjectSpecific::TRACE_LIGHTS;
	if		((!O->renderable_ShadowGenerate()) && (!O->renderable_ShadowReceive()))	bTraceLights = FALSE;
	if		(bTraceLights)	{
		// Select nearest lights
		Fvector					bb_size	=	{radius,radius,radius};
		g_SpatialSpace->q_box				(RImplementation.lstSpatial,0,STYPE_LIGHTSOURCE,position,bb_size);
		for (u32 o_it=0; o_it<RImplementation.lstSpatial.size(); o_it++)	{
			ISpatial*	spatial		= RImplementation.lstSpatial[o_it];
			light*		source		= (light*)	(spatial->dcast_Light());
			VERIFY		(source);	// sanity check
			float	R				= radius+source->range;
			if (position.distance_to(source->position) < R)		add	(source);
		}

		// Trace visibility
		lights.clear	();
		float traceR	= radius*.5f;
		for (s32 id=0; id<s32(track.size()); id++)
		{
			// remove untouched lights
			xr_vector<CROS_impl::Item>::iterator I	= track.begin()+id;
			if (I->frame_touched!=Device.dwFrame)	{ track.erase(I) ; id--	; continue ; }

			// Trace visibility
			Fvector				P,D;
			float		amount	= 0;
			light*		xrL		= I->source;
			Fvector&	LP		= xrL->position;
			P.mad				(position,P.random_dir(),traceR);		// Random point inside range

			// point/spot
			float	f			=	D.sub(P,LP).magnitude();
			if (g_pGameLevel->ObjectSpace.RayTest(LP,D.div(f),f,collide::rqtStatic,&I->cache,_object))	amount -=	lt_dec;
			else																						amount +=	lt_inc;
			I->test				+=	amount * dt;	clamp	(I->test,-.5f,1.f);
			I->energy			=	.9f*I->energy + .1f*I->test;

			// 
			float	E			=	I->energy * xrL->color.intensity	();
			if (E > EPS)		{
				// Select light
				lights.push_back			(CROS_impl::Light())		;
				CROS_impl::Light&	L		= lights.back()				;
				L.source					= xrL						;
				L.color.mul_rgb				(xrL->color,I->energy/2)	;
				L.energy					= I->energy/2				;
				if (!xrL->flags.bStatic)	{ L.color.mul_rgb(.5f); L.energy *= .5f; }
			}
		}

		// Sun
		float	E			=	sun_smooth * sun->color.intensity	();
		if (E > EPS)		{
			// Select light
			lights.push_back			(CROS_impl::Light())		;
			CROS_impl::Light&	L		= lights.back()				;
			L.source					= sun						;
			L.color.mul_rgb				(sun->color,sun_smooth/2)	;
			L.energy					= sun_smooth				;
		}

		// Sort lights by importance - important for R1-shadows
		std::sort	(lights.begin(),lights.end(), pred_energy);
	}

	// Process ambient lighting and approximate average lighting
	// Process our lights to find average luminiscense
	CEnvDescriptor&	desc	=	g_pGamePersistent->Environment().CurrentEnv;
	Fvector			accum	=	{ desc.ambient.x,		desc.ambient.y,		desc.ambient.z		};
	Fvector			hemi	=	{ desc.hemi_color.x,	desc.hemi_color.y,	desc.hemi_color.z	};
	Fvector			sun_	=	{ desc.sun_color.x,		desc.sun_color.y,	desc.sun_color.z	};
	if (MODE & IRender_ObjectSpecific::TRACE_HEMI	)	hemi.mul(hemi_smooth); else hemi.mul(.2f);
					accum.add	( hemi );
	if (MODE & IRender_ObjectSpecific::TRACE_SUN	)	sun_.mul(sun_smooth); else sun_.mul(.2f);
					accum.add	( sun_ );
	if (MODE & IRender_ObjectSpecific::TRACE_LIGHTS )	{
		Fvector		lacc	=	{ 0,0,0 };
		for (u32 lit=0; lit<lights.size(); lit++)	{
			float	d	=	lights[lit].source->position.distance_to(position);
			float	r	=	lights[lit].source->range;
			float	a	=	clampr(1.f - d/(r+EPS),0.f,1.f)*(lights[lit].source->flags.bStatic?1.f:2.f);
			lacc.x		+=	lights[lit].color.r*a;
			lacc.y		+=	lights[lit].color.g*a;
			lacc.z		+=	lights[lit].color.b*a;
		}
//		lacc.x		*= desc.lmap_color.x;
//		lacc.y		*= desc.lmap_color.y;
//		lacc.z		*= desc.lmap_color.z;
//		Msg				("- rgb[%f,%f,%f]",lacc.x,lacc.y,lacc.z);
		accum.add		(lacc);
	} else 			accum.set	( .1f, .1f, .1f );
	approximate				=	accum;
}