void CPortalTraverser::fade_render () { if (f_portals.empty()) return; // re-sort, back to front std::sort (f_portals.begin(),f_portals.end(),psort_pred); // calc poly-count u32 _pcount = 0; for (u32 _it = 0; _it<f_portals.size(); _it++) _pcount += f_portals[_it].first->getPoly().size()-2; // fill buffers u32 _offset = 0; FVF::L* _v = (FVF::L*)RCache.Vertex.Lock(_pcount*3,f_geom.stride(),_offset); float ssaRange = r_ssaLOD_A - r_ssaLOD_B; Fvector _ambient_f = g_pGamePersistent->Environment().CurrentEnv.ambient; u32 _ambient = color_rgba_f (_ambient_f.x,_ambient_f.y,_ambient_f.z,0); for (u32 _it = 0; _it<f_portals.size(); _it++) { std::pair<CPortal*, float>& fp = f_portals [_it] ; CPortal* _P = fp.first ; float _ssa = fp.second ; float ssaDiff = _ssa-r_ssaLOD_B ; float ssaScale = ssaDiff/ssaRange ; int iA = iFloor((1-ssaScale)*255.5f); clamp(iA,0,255); u32 _clr = subst_alpha(_ambient,u32(iA)); // fill polys u32 _polys = _P->getPoly().size()-2; for (u32 _pit=0; _pit<_polys; _pit++) { _v->set (_P->getPoly()[0], _clr); _v++; _v->set (_P->getPoly()[_pit+1],_clr); _v++; _v->set (_P->getPoly()[_pit+2],_clr); _v++; } } RCache.Vertex.Unlock (_pcount*3,f_geom.stride()); // render RCache.set_xform_world (Fidentity); RCache.set_Shader (f_shader); RCache.set_Geometry (f_geom); RCache.set_CullMode (CULL_NONE); RCache.Render (D3DPT_TRIANGLELIST,_offset,_pcount); RCache.set_CullMode (CULL_CCW); // cleanup f_portals.clear (); }
void CLevelTools::GetCurrentFog(u32& fog_color, float& s_fog, float& e_fog) { if (psDeviceFlags.is(rsEnvironment)&&psDeviceFlags.is(rsFog)){ s_fog = g_pGamePersistent->Environment().CurrentEnv.fog_near; e_fog = g_pGamePersistent->Environment().CurrentEnv.fog_far; Fvector& f_clr = g_pGamePersistent->Environment().CurrentEnv.fog_color; fog_color = color_rgba_f(f_clr.x,f_clr.y,f_clr.z,1.f); }else{ s_fog = psDeviceFlags.is(rsFog)?(1.0f - fFogness)* 0.85f * UI->ZFar():0.99f*UI->ZFar(); e_fog = psDeviceFlags.is(rsFog)?0.91f * UI->ZFar():UI->ZFar(); fog_color = dwFogColor; } /* //. f_near = g_pGamePersistent->Environment.Current.fog_near; f_far = 1/(g_pGamePersistent->Environment.Current.fog_far - f_near); */ }
void dxEnvironmentRender::OnFrame(CEnvironment &env) { dxEnvDescriptorMixerRender &mixRen = *(dxEnvDescriptorMixerRender*)&*env.CurrentEnv->m_pDescriptorMixer; 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 mixRen.sky_r_textures.push_back (mk_pair(u32(D3DVERTEXTEXTURESAMPLER0),tonemap)); //. hack mixRen.sky_r_textures_env.push_back (mk_pair(u32(D3DVERTEXTEXTURESAMPLER0),tonemap)); //. hack mixRen.clouds_r_textures.push_back (mk_pair(u32(D3DVERTEXTEXTURESAMPLER0),tonemap)); //. hack } else { // tonemapping in PS mixRen.sky_r_textures.push_back (mk_pair(2,tonemap)); //. hack mixRen.sky_r_textures_env.push_back (mk_pair(2,tonemap)); //. hack mixRen.clouds_r_textures.push_back (mk_pair(2,tonemap)); //. hack } } //. Setup skybox textures, somewhat ugly ID3DBaseTexture* e0 = mixRen.sky_r_textures[0].second->surface_get(); ID3DBaseTexture* e1 = mixRen.sky_r_textures[1].second->surface_get(); tsky0->surface_set (e0); _RELEASE(e0); tsky1->surface_set (e1); _RELEASE(e1); // ******************** Environment params (setting) #ifdef USE_DX10 // TODO: DX10: Implement environment parameters setting for DX10 (if necessary) #else // USE_DX10 #if RENDER==R_R1 Fvector3 fog_color = env.CurrentEnv->fog_color; fog_color.mul(ps_r1_fog_luminance); #else // RENDER==R_R1 Fvector3 &fog_color = env.CurrentEnv->fog_color; #endif // RENDER==R_R1 CHK_DX(HW.pDevice->SetRenderState( D3DRS_FOGCOLOR, color_rgba_f(fog_color.x,fog_color.y,fog_color.z,0) )); CHK_DX(HW.pDevice->SetRenderState( D3DRS_FOGSTART, *(u32 *)(&env.CurrentEnv->fog_near) )); CHK_DX(HW.pDevice->SetRenderState( D3DRS_FOGEND, *(u32 *)(&env.CurrentEnv->fog_far) )); #endif // USE_DX10 }
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) )); }
void CLightProjector::calculate () { #ifdef _GPA_ENABLED TAL_SCOPED_TASK_NAMED( "CLightProjector::calculate()" ); #endif // _GPA_ENABLED if (receivers.empty()) return; // perform validate / markup for (u32 r_it=0; r_it<receivers.size(); r_it++) { // validate BOOL bValid = TRUE; IRenderable* O = receivers[r_it]; CROS_impl* LT = (CROS_impl*)O->renderable_ROS(); int slot = LT->shadow_recv_slot; if (slot<0 || slot>=P_o_count) bValid = FALSE; // invalid slot else if (cache[slot].O!=O) bValid = FALSE; // not the same object else { // seems to be valid Fbox bb; bb.xform (O->renderable.visual->getVisData().box,O->renderable.xform); if (cache[slot].BB.contains(bb)) { // inside, but maybe timelimit exceeded? if (Device.dwTimeGlobal > cache[slot].dwTimeValid) bValid = FALSE; // timeout } else bValid = FALSE; // out of bounds } // if (bValid) { // Ok, use cached version cache[slot].dwFrame = Device.dwFrame; } else { taskid.push_back (r_it); } } if (taskid.empty()) return; // Begin Device.Statistic->RenderDUMP_Pcalc.Begin (); RCache.set_RT (RT->pRT); RCache.set_ZB (RImplementation.Target->pTempZB); CHK_DX(HW.pDevice->Clear (0,0, D3DCLEAR_ZBUFFER | (HW.Caps.bStencil?D3DCLEAR_STENCIL:0), 0,1,0 )); RCache.set_xform_world (Fidentity); // reallocate/reassociate structures + perform all the work for (u32 c_it=0; c_it<cache.size(); c_it++) { if (taskid.empty()) break; if (Device.dwFrame==cache[c_it].dwFrame) continue; // found not used slot int tid = taskid.back(); taskid.pop_back(); recv& R = cache [c_it]; IRenderable* O = receivers [tid]; const vis_data& vis = O->renderable.visual->getVisData(); CROS_impl* LT = (CROS_impl*)O->renderable_ROS(); VERIFY2 (_valid(O->renderable.xform),"Invalid object transformation"); VERIFY2 (_valid(vis.sphere.P),"Invalid object's visual sphere"); Fvector C; O->renderable.xform.transform_tiny (C,vis.sphere.P); R.O = O; R.C = C; R.C.y += vis.sphere.R*0.1f; //. YURA: 0.1 can be more R.BB.xform (vis.box,O->renderable.xform).scale(0.1f); R.dwTimeValid = Device.dwTimeGlobal + ::Random.randI(time_min,time_max); LT->shadow_recv_slot = c_it; // Msg ("[%f,%f,%f]-%f",C.C.x,C.C.y,C.C.z,C.O->renderable.visual->vis.sphere.R); // calculate projection-matrix Fmatrix mProject; float p_R = R.O->renderable.visual->getVisData().sphere.R * 1.1f; //VERIFY2 (p_R>EPS_L,"Object has no physical size"); VERIFY3 (p_R>EPS_L,"Object has no physical size", R.O->renderable.visual->getDebugName().c_str()); float p_hat = p_R/P_cam_dist; float p_asp = 1.f; float p_near = P_cam_dist-EPS_L; float p_far = P_cam_dist+p_R+P_cam_range; mProject.build_projection_HAT (p_hat,p_asp,p_near,p_far); RCache.set_xform_project (mProject); // calculate view-matrix Fmatrix mView; Fvector v_C, v_Cs, v_N; v_C.set (R.C); v_Cs = v_C; v_C.y += P_cam_dist; v_N.set (0,0,1); VERIFY (_valid(v_C) && _valid(v_Cs) && _valid(v_N)); // validate Fvector v; v.sub (v_Cs,v_C);; #ifdef DEBUG if ((v.x*v.x+v.y*v.y+v.z*v.z)<=flt_zero) { CObject* OO = dynamic_cast<CObject*>(R.O); Msg("Object[%s] Visual[%s] has invalid position. ",*OO->cName(),*OO->cNameVisual()); Fvector cc; OO->Center(cc); Log("center=",cc); Log("visual_center=",OO->Visual()->getVisData().sphere.P); Log("full_matrix=",OO->XFORM()); Log ("v_N",v_N); Log ("v_C",v_C); Log ("v_Cs",v_Cs); Log("all bones transform:--------"); CKinematics* K = dynamic_cast<CKinematics*>(OO->Visual()); for(u16 ii=0; ii<K->LL_BoneCount();++ii){ Fmatrix tr; tr = K->LL_GetTransform(ii); Log("bone ",K->LL_BoneName_dbg(ii)); Log("bone_matrix",tr); } Log("end-------"); } #endif // handle invalid object-bug if ((v.x*v.x+v.y*v.y+v.z*v.z)<=flt_zero) { // invalidate record, so that object will be unshadowed, but doesn't crash R.dwTimeValid = Device.dwTimeGlobal; LT->shadow_recv_frame = Device.dwFrame-1; LT->shadow_recv_slot = -1; continue ; } mView.build_camera (v_C,v_Cs,v_N); RCache.set_xform_view (mView); // Select slot, set viewport int s_x = c_it%P_o_line; int s_y = c_it/P_o_line; D3DVIEWPORT9 VP = {s_x*P_o_size,s_y*P_o_size,P_o_size,P_o_size,0,1 }; CHK_DX (HW.pDevice->SetViewport(&VP)); // Clear color to ambience Fvector& cap = LT->get_approximate(); CHK_DX (HW.pDevice->Clear(0,0, D3DCLEAR_TARGET, color_rgba_f(cap.x,cap.y,cap.z, (cap.x+cap.y+cap.z)/4.f), 1, 0 )); // calculate uv-gen matrix and clamper Fmatrix mCombine; mCombine.mul (mProject,mView); Fmatrix mTemp; float fSlotSize = float(P_o_size)/float(P_rt_size); float fSlotX = float(s_x*P_o_size)/float(P_rt_size); float fSlotY = float(s_y*P_o_size)/float(P_rt_size); float fTexelOffs = (.5f / P_rt_size); Fmatrix m_TexelAdjust = { 0.5f/*x-scale*/, 0.0f, 0.0f, 0.0f, 0.0f, -0.5f/*y-scale*/, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f/*z-range*/, 0.0f, 0.5f/*x-bias*/, 0.5f + fTexelOffs/*y-bias*/, 0.0f/*z-bias*/, 1.0f }; R.UVgen.mul (m_TexelAdjust,mCombine); mTemp.scale (fSlotSize,fSlotSize,1); R.UVgen.mulA_44 (mTemp); mTemp.translate (fSlotX+fTexelOffs,fSlotY+fTexelOffs,0); R.UVgen.mulA_44 (mTemp); // Build bbox and render Fvector min,max; Fbox BB; min.set (R.C.x-p_R, R.C.y-(p_R+P_cam_range), R.C.z-p_R); max.set (R.C.x+p_R, R.C.y+0, R.C.z+p_R); BB.set (min,max); R.UVclamp_min.set (min).add (.05f); // shrink a little R.UVclamp_max.set (max).sub (.05f); // shrink a little ISpatial* spatial = dynamic_cast<ISpatial*> (O); if (spatial) { spatial->spatial_updatesector (); if (spatial->spatial.sector) RImplementation.r_dsgraph_render_R1_box (spatial->spatial.sector,BB,SE_R1_LMODELS); } //if (spatial) RImplementation.r_dsgraph_render_subspace (spatial->spatial.sector,mCombine,v_C,FALSE); } // Blur /* { // Fill vertex buffer u32 Offset; FVF::TL4uv* pv = (FVF::TL4uv*) RCache.Vertex.Lock (4,geom_Blur.stride(),Offset); RImplementation.ApplyBlur4 (pv,P_rt_size,P_rt_size,P_blur_kernel); RCache.Vertex.Unlock (4,geom_Blur.stride()); // Actual rendering (pass0, temp2real) RCache.set_RT (RT->pRT); RCache.set_ZB (NULL); RCache.set_Shader (sh_BlurTR ); RCache.set_Geometry (geom_Blur ); RCache.Render (D3DPT_TRIANGLELIST,Offset,0,4,0,2); } */ // Finita la comedia Device.Statistic->RenderDUMP_Pcalc.End (); RCache.set_xform_project (Device.mProject); RCache.set_xform_view (Device.mView); }