void IGame_Persistent::OnGameStart() { #ifndef _EDITOR LoadTitle ("st_prefetching_objects"); if (strstr(Core.Params,"-noprefetch")) return; // prefetch game objects & models float p_time = 1000.f*Device.GetTimerGlobal()->GetElapsed_sec(); u32 mem_0 = Memory.mem_usage() ; Log ("Loading objects..."); ObjectPool.prefetch (); Log ("Loading models..."); Render->models_Prefetch (); //Device.Resources->DeferredUpload (); Device.m_pRender->ResourcesDeferredUpload(); p_time = 1000.f*Device.GetTimerGlobal()->GetElapsed_sec() - p_time; u32 p_mem = Memory.mem_usage() - mem_0 ; Msg ("* [prefetch] time: %d ms", iFloor(p_time)); Msg ("* [prefetch] memory: %dKb", p_mem/1024); #endif }
void dxEnvironmentRender::RenderClouds(CEnvironment &env) { ::Render->rmFar (); Fmatrix mXFORM, mScale; mScale.scale (10,0.4f,10); mXFORM.rotateY (env.CurrentEnv->sky_rotation); mXFORM.mulB_43 (mScale); mXFORM.translate_over (Device.vCameraPosition); Fvector wd0,wd1; Fvector4 wind_dir; wd0.setHP (PI_DIV_4,0); wd1.setHP (PI_DIV_4+PI_DIV_8,0); wind_dir.set (wd0.x,wd0.z,wd1.x,wd1.z).mul(0.5f).add(0.5f).mul(255.f); u32 i_offset,v_offset; u32 C0 = color_rgba(iFloor(wind_dir.x),iFloor(wind_dir.y),iFloor(wind_dir.w),iFloor(wind_dir.z)); u32 C1 = color_rgba(iFloor(env.CurrentEnv->clouds_color.x*255.f),iFloor(env.CurrentEnv->clouds_color.y*255.f),iFloor(env.CurrentEnv->clouds_color.z*255.f),iFloor(env.CurrentEnv->clouds_color.w*255.f)); // Fill index buffer u16* pib = RCache.Index.Lock (env.CloudsIndices.size(),i_offset); CopyMemory (pib,&env.CloudsIndices.front(),env.CloudsIndices.size()*sizeof(u16)); RCache.Index.Unlock (env.CloudsIndices.size()); // Fill vertex buffer v_clouds* pv = (v_clouds*) RCache.Vertex.Lock (env.CloudsVerts.size(),clouds_geom.stride(),v_offset); for (FvectorIt it=env.CloudsVerts.begin(); it!=env.CloudsVerts.end(); it++,pv++) pv->set (*it,C0,C1); RCache.Vertex.Unlock (env.CloudsVerts.size(),clouds_geom.stride()); // Render RCache.set_xform_world (mXFORM); RCache.set_Geometry (clouds_geom); RCache.set_Shader (clouds_sh); dxEnvDescriptorMixerRender &mixRen = *(dxEnvDescriptorMixerRender*)&*env.CurrentEnv->m_pDescriptorMixer; RCache.set_Textures (&mixRen.clouds_r_textures); RCache.Render (D3DPT_TRIANGLELIST,v_offset,0,env.CloudsVerts.size(),i_offset,env.CloudsIndices.size()/3); ::Render->rmNormal (); }
void xrBuildNodes() { // begin XRC.box_options (CDB::OPT_FULL_TEST); XRC.ray_options (CDB::OPT_CULL | CDB::OPT_ONLYNEAREST); g_nodes.reserve (1024*1024); // Initialize hash hash_Initialize (); for (u32 em=0; em<Emitters.size(); em++) { // Align emitter Fvector Pos = Emitters[em]; SnapXZ (Pos); Pos.y +=1; Fvector Dir; Dir.set(0,-1,0); XRC.ray_query (&Level,Pos,Dir,3); if (XRC.r_count()==0) { Msg ("Can't align emitter"); abort (); } else { CDB::RESULT& R = *XRC.r_begin(); Pos.y = Pos.y - R.range; } // Build first node int oldcount = g_nodes.size(); int start = BuildNode (Pos,Pos); if (start==InvalidNode) continue; if (start<oldcount) continue; // Estimate nodes Fvector LevelSize; LevelBB.getsize (LevelSize); u32 estimated_nodes = iFloor(LevelSize.x/g_params.fPatchSize)*iFloor(LevelSize.z/g_params.fPatchSize); // General cycle for (u32 i=0; i<g_nodes.size(); i++) { // left if (g_nodes[i].n1==UnkonnectedNode) { Pos.set (g_nodes[i].Pos); Pos.x -= g_params.fPatchSize; int id = BuildNode(g_nodes[i].Pos,Pos); g_nodes[i].n1 = id; } // fwd if (g_nodes[i].n2==UnkonnectedNode) { Pos.set (g_nodes[i].Pos); Pos.z += g_params.fPatchSize; int id = BuildNode(g_nodes[i].Pos,Pos); g_nodes[i].n2 = id; } // right if (g_nodes[i].n3==UnkonnectedNode) { Pos.set (g_nodes[i].Pos); Pos.x += g_params.fPatchSize; int id = BuildNode(g_nodes[i].Pos,Pos); g_nodes[i].n3 = id; } // back if (g_nodes[i].n4==UnkonnectedNode) { Pos.set (g_nodes[i].Pos); Pos.z -= g_params.fPatchSize; int id = BuildNode(g_nodes[i].Pos,Pos); g_nodes[i].n4 = id; } if (i%512==0) { Status("%d / %d nodes created.",g_nodes.size()-i,g_nodes.size()); float p1 = float(i)/float(g_nodes.size()); float p2 = float(g_nodes.size())/estimated_nodes; float p = 0.1f*p1+0.9f*p2; clamp (p,0.f,1.f); Progress(p); } } } Msg("Freeing memory..."); hash_Destroy (); }
Vector2int32::Vector2int32(const class Vector2& v) { x = (int32)iFloor(v.x + 0.5); y = (int32)iFloor(v.y + 0.5); }
// Calculate T&B void OGF::CalculateTB() { u32 v_count_reserve = 3*iFloor(float(data.vertices.size())*1.33f); u32 i_count_reserve = 3*data.faces.size(); // Declare inputs xr_vector<NVMeshMender::VertexAttribute> input; input.push_back (NVMeshMender::VertexAttribute()); // pos input.push_back (NVMeshMender::VertexAttribute()); // norm input.push_back (NVMeshMender::VertexAttribute()); // tex0 input.push_back (NVMeshMender::VertexAttribute()); // color input.push_back (NVMeshMender::VertexAttribute()); // *** faces input[0].Name_= "position"; xr_vector<float>& i_position = input[0].floatVector_; i_position.reserve (v_count_reserve); input[1].Name_= "normal"; xr_vector<float>& i_normal = input[1].floatVector_; i_normal.reserve (v_count_reserve); input[2].Name_= "tex0"; xr_vector<float>& i_tc = input[2].floatVector_; i_tc.reserve (v_count_reserve); input[3].Name_= "clr"; xr_vector<float>& i_color = input[3].floatVector_; i_normal.reserve (v_count_reserve); input[4].Name_= "indices"; xr_vector<int>& i_indices = input[4].intVector_; i_indices.reserve (i_count_reserve); // Declare outputs xr_vector<NVMeshMender::VertexAttribute> output; output.push_back(NVMeshMender::VertexAttribute()); // position, needed for mender output.push_back(NVMeshMender::VertexAttribute()); // normal output.push_back(NVMeshMender::VertexAttribute()); // tangent output.push_back(NVMeshMender::VertexAttribute()); // binormal output.push_back(NVMeshMender::VertexAttribute()); // tex0 output.push_back(NVMeshMender::VertexAttribute()); // color output.push_back(NVMeshMender::VertexAttribute()); // *** faces output[0].Name_= "position"; output[1].Name_= "normal"; output[2].Name_= "tangent"; output[3].Name_= "binormal"; output[4].Name_= "tex0"; output[5].Name_= "clr"; output[6].Name_= "indices"; fill_mender_input( data.vertices, data.faces, i_position, i_normal, i_tc, i_color, i_indices ); // Perform munge NVMeshMender mender; if (!mender.Munge( input, // input attributes output, // outputs attributes deg2rad(75.f), // tangent space smooth angle 0, // no texture matrix applied to my texture coordinates NVMeshMender::FixTangents, // fix degenerate bases & texture mirroring NVMeshMender::DontFixCylindricalTexGen, // handle cylindrically mapped textures via vertex duplication NVMeshMender::DontWeightNormalsByFaceSize // weigh vertex normals by the triangle's size )) { xrDebug::Fatal (DEBUG_INFO,"NVMeshMender failed (%s)",mender.GetLastError().c_str()); } // Bind declarators xr_vector<float>& o_position = output[0].floatVector_; R_ASSERT(output[0].Name_=="position"); xr_vector<float>& o_normal = output[1].floatVector_; R_ASSERT(output[1].Name_=="normal"); xr_vector<float>& o_tangent = output[2].floatVector_; R_ASSERT(output[2].Name_=="tangent"); xr_vector<float>& o_binormal = output[3].floatVector_; R_ASSERT(output[3].Name_=="binormal"); xr_vector<float>& o_tc = output[4].floatVector_; R_ASSERT(output[4].Name_=="tex0"); xr_vector<float>& o_color = output[5].floatVector_; R_ASSERT(output[5].Name_=="clr"); xr_vector<int>& o_indices = output[6].intVector_; R_ASSERT(output[6].Name_=="indices"); // verify R_ASSERT (3*data.faces.size() == o_indices.size()); u32 v_cnt = o_position.size(); R_ASSERT (0==v_cnt%3); R_ASSERT (v_cnt == o_normal.size()); R_ASSERT (v_cnt == o_tangent.size()); R_ASSERT (v_cnt == o_binormal.size()); R_ASSERT (v_cnt == o_tc.size()); R_ASSERT (v_cnt == o_color.size()); retrive_data_from_mender_otput( data.vertices, data.faces, o_position, o_normal, o_tc, o_tangent, o_binormal, o_color, o_indices ); }
IC BYTE compress(float c, int max_value) { int cover = iFloor(c*float(max_value)+.5f); clamp(cover,0,max_value); return BYTE(cover); }
void CHUDTarget::Render() { VERIFY (g_bRendering); CObject* O = Level().CurrentEntity(); if (0==O) return; CEntity* E = smart_cast<CEntity*>(O); if (0==E) return; Fvector p1 = Device.vCameraPosition; Fvector dir = Device.vCameraDirection; // Render cursor u32 C = C_DEFAULT; FVF::TL PT; Fvector p2; p2.mad (p1,dir,RQ.range); PT.transform (p2,Device.mFullTransform); float di_size = C_SIZE/powf(PT.p.w,.2f); CGameFont* F = HUD().Font().pFontGraffiti19Russian; F->SetAligment (CGameFont::alCenter); F->OutSetI (0.f,0.05f); if (psHUD_Flags.test(HUD_CROSSHAIR_DIST)){ F->SetColor (C); F->OutNext ("%4.1f",RQ.range); } if (psHUD_Flags.test(HUD_INFO)){ if (RQ.O){ CEntityAlive* E = smart_cast<CEntityAlive*> (RQ.O); CEntityAlive* pCurEnt = smart_cast<CEntityAlive*> (Level().CurrentEntity()); PIItem l_pI = smart_cast<PIItem> (RQ.O); if (IsGameTypeSingle()) { CInventoryOwner* our_inv_owner = smart_cast<CInventoryOwner*>(pCurEnt); if (E && E->g_Alive() && !E->cast_base_monster()) { //. CInventoryOwner* our_inv_owner = smart_cast<CInventoryOwner*>(pCurEnt); CInventoryOwner* others_inv_owner = smart_cast<CInventoryOwner*>(E); if(our_inv_owner && others_inv_owner){ switch(RELATION_REGISTRY().GetRelationType(others_inv_owner, our_inv_owner)) { case ALife::eRelationTypeEnemy: C = C_ON_ENEMY; break; case ALife::eRelationTypeNeutral: C = C_ON_NEUTRAL; break; case ALife::eRelationTypeFriend: C = C_ON_FRIEND; break; } if (fuzzyShowInfo>0.5f){ CStringTable strtbl ; F->SetColor (subst_alpha(C,u8(iFloor(255.f*(fuzzyShowInfo-0.5f)*2.f)))); F->OutNext ("%s", *strtbl.translate(others_inv_owner->Name()) ); F->OutNext ("%s", *strtbl.translate(others_inv_owner->CharacterInfo().Community().id()) ); } } fuzzyShowInfo += SHOW_INFO_SPEED*Device.fTimeDelta; } else if (l_pI && our_inv_owner && RQ.range < 2.0f*our_inv_owner->inventory().GetTakeDist()) { if (fuzzyShowInfo>0.5f){ F->SetColor (subst_alpha(C,u8(iFloor(255.f*(fuzzyShowInfo-0.5f)*2.f)))); F->OutNext ("%s",l_pI->Name/*Complex*/()); } fuzzyShowInfo += SHOW_INFO_SPEED*Device.fTimeDelta; } } else { if (E && (E->GetfHealth()>0)) { if (pCurEnt && GameID() == GAME_SINGLE){ if (GameID() == GAME_DEATHMATCH) C = C_ON_ENEMY; else{ if (E->g_Team() != pCurEnt->g_Team()) C = C_ON_ENEMY; else C = C_ON_FRIEND; }; if (RQ.range >= recon_mindist() && RQ.range <= recon_maxdist()){ float ddist = (RQ.range - recon_mindist())/(recon_maxdist() - recon_mindist()); float dspeed = recon_minspeed() + (recon_maxspeed() - recon_minspeed())*ddist; fuzzyShowInfo += Device.fTimeDelta/dspeed; }else{ if (RQ.range < recon_mindist()) fuzzyShowInfo += recon_minspeed()*Device.fTimeDelta; else fuzzyShowInfo = 0; }; if (fuzzyShowInfo>0.5f){ clamp(fuzzyShowInfo,0.f,1.f); int alpha_C = iFloor(255.f*(fuzzyShowInfo-0.5f)*2.f); u8 alpha_b = u8(alpha_C & 0x00ff); F->SetColor (subst_alpha(C,alpha_b)); F->OutNext ("%s",*RQ.O->cName()); } } }; }; }else{ fuzzyShowInfo -= HIDE_INFO_SPEED*Device.fTimeDelta; } clamp(fuzzyShowInfo,0.f,1.f); } //отрендерить кружочек или крестик if(!m_bShowCrosshair){ // actual rendering u32 vOffset; FVF::TL* pv = (FVF::TL*)RCache.Vertex.Lock(4,hGeom.stride(),vOffset); float size_x = float(Device.dwWidth) * di_size; float size_y = float(Device.dwHeight) * di_size; size_y = size_x; float w_2 = Device.fWidth_2; float h_2 = Device.fHeight_2; // Convert to screen coords float cx = (PT.p.x+1)*w_2; float cy = (PT.p.y+1)*h_2; pv->set (cx - size_x, cy + size_y, C, 0, 1); ++pv; pv->set (cx - size_x, cy - size_y, C, 0, 0); ++pv; pv->set (cx + size_x, cy + size_y, C, 1, 1); ++pv; pv->set (cx + size_x, cy - size_y, C, 1, 0); ++pv; // unlock VB and Render it as triangle LIST RCache.Vertex.Unlock(4,hGeom.stride()); RCache.set_Shader (hShader); RCache.set_Geometry (hGeom); RCache.Render (D3DPT_TRIANGLELIST,vOffset,0,4,0,2); }else{ //отрендерить прицел HUDCrosshair.cross_color = C; HUDCrosshair.OnRender (); } }
const String& CompassDirection::nearestCompassPointAbbreviation() const { // Change names every 12.5 degrees, offset slightly const int i = iFloor(wrap(m_angleDegrees + (360 / 64.0f), 360) / 32); debugAssertM(i >= 0 && i < 32, "Index out of bounds"); return NAME_TABLE[2 * i + 1]; }
void CUITrackBar::UpdatePosRelativeToMouse() { float _bkf = 0.0f; int _bki = 0; if(m_b_is_float) { _bkf = m_f_val; }else { _bki = m_i_val; } float btn_width = m_pSlider->GetWidth(); float window_width = GetWidth(); //float fpos = cursor_pos.x; // Start.Real Wolf.06.11.14. Fvector2 pos; GetAbsolutePos(pos); float fpos = GetUICursor()->GetCursorPosition().x - pos.x; // Finish.Real Wolf.06.11.14. if( GetInvert() ) fpos = window_width - fpos; if (fpos < btn_width/2) fpos = btn_width/2; else if (fpos > window_width - btn_width/2) fpos = window_width - btn_width/2; float __fval; float __fmax = (m_b_is_float)?m_f_max:(float)m_i_max; float __fmin = (m_b_is_float)?m_f_min:(float)m_i_min; float __fstep = (m_b_is_float)?m_f_step:(float)m_i_step; __fval = (__fmax - __fmin)*(fpos - btn_width/2)/(window_width - btn_width)+ __fmin; float _d = (__fval-__fmin); float _v = _d/__fstep; int _vi = iFloor(_v); float _vf = __fstep*_vi; if(_d-_vf>__fstep/2.0f) _vf += __fstep; __fval = __fmin+_vf; clamp (__fval, __fmin, __fmax); if(m_b_is_float) m_f_val = __fval; else m_i_val = iFloor(__fval); bool b_ch = false; if(m_b_is_float) { b_ch = !fsimilar(_bkf, m_f_val); }else { b_ch = (_bki != m_i_val); } if(b_ch) GetMessageTarget()->SendMessage(this, BUTTON_CLICKED, NULL); UpdatePos (); }
Vector3int16 Vector3int16::floor(const Vector3& v) { return Vector3int16(iFloor(v.x), iFloor(v.y), iFloor(v.z)); }
Vector3int16::Vector3int16(const class Vector3& v) { x = (int16)iFloor(v.x + 0.5); y = (int16)iFloor(v.y + 0.5); z = (int16)iFloor(v.z + 0.5); }
BOOL CDemoPlay::ProcessCam(SCamEffectorInfo& info) { // skeep a few frames before counting if (Device.dwPrecacheFrame) return TRUE; if (stat_started) { //g_SASH.DisplayFrame(Device.fTimeGlobal); } else { //g_SASH.StartBenchmark(); stat_Start(); } // Per-frame statistics { stat_table.push_back (stat_Timer_frame.GetElapsed_sec()); stat_Timer_frame.Start (); } // Process motion if (m_pMotion) { Fvector R; Fmatrix mRotate; m_pMotion->_Evaluate (m_MParam->Frame(),info.p,R); m_MParam->Update (Device.fTimeDelta,1.f,true); fLifeTime -= Device.fTimeDelta; if (m_MParam->bWrapped) { stat_Stop(); stat_Start(); } mRotate.setXYZi (R.x,R.y,R.z); info.d.set (mRotate.k); info.n.set (mRotate.j); } else { if (seq.empty()) { g_pGameLevel->Cameras().RemoveCamEffector(cefDemo); return TRUE; } fStartTime += Device.fTimeDelta; float ip; float p = fStartTime/fSpeed; float t = modff(p, &ip); int frame = iFloor(ip); VERIFY (t>=0); if (frame>=m_count) { dwCyclesLeft -- ; if (0==dwCyclesLeft) return FALSE; fStartTime = 0 ; // just continue // stat_Stop (); // stat_Start (); } int f1=frame; FIX(f1); int f2=f1+1; FIX(f2); int f3=f2+1; FIX(f3); int f4=f3+1; FIX(f4); Fmatrix *m1,*m2,*m3,*m4; Fvector v[4]; m1 = (Fmatrix *) &seq[f1]; m2 = (Fmatrix *) &seq[f2]; m3 = (Fmatrix *) &seq[f3]; m4 = (Fmatrix *) &seq[f4]; for (int i=0; i<4; i++) { v[0].x = m1->m[i][0]; v[0].y = m1->m[i][1]; v[0].z = m1->m[i][2]; v[1].x = m2->m[i][0]; v[1].y = m2->m[i][1]; v[1].z = m2->m[i][2]; v[2].x = m3->m[i][0]; v[2].y = m3->m[i][1]; v[2].z = m3->m[i][2]; v[3].x = m4->m[i][0]; v[3].y = m4->m[i][1]; v[3].z = m4->m[i][2]; spline1 ( t, &(v[0]), (Fvector *) &(Device.mView.m[i][0]) ); } Fmatrix mInvCamera; mInvCamera.invert(Device.mView); info.n.set( mInvCamera._21, mInvCamera._22, mInvCamera._23 ); info.d.set( mInvCamera._31, mInvCamera._32, mInvCamera._33 ); info.p.set( mInvCamera._41, mInvCamera._42, mInvCamera._43 ); fLifeTime-=Device.fTimeDelta; } return TRUE; }
void CGameFont::OnRender() { VERIFY (g_bRendering); if (pShader) RCache.set_Shader (pShader); if (!(uFlags&fsValid)){ CTexture* T = RCache.get_ActiveTexture(0); vTS.set ((int)T->get_Width(),(int)T->get_Height()); /* vHalfPixel.set (0.5f/float(vTS.x),0.5f/float(vTS.y)); for (int i=0; i<256; i++){ Fvector& tc = TCMap[i]; tc.x /= float(vTS.x); tc.y /= float(vTS.y); tc.z /= float(vTS.x); } fTCHeight = fHeight/float(vTS.y); uFlags |= fsValid; */ fTCHeight = fHeight/float(vTS.y); uFlags |= fsValid; } for (u32 i=0; i<strings.size(); ){ // calculate first-fit int count = 1; int length = xr_strlen(strings[i].string); while ((i+count)<strings.size()) { int L = xr_strlen(strings[i+count].string); if ((L+length)<MAX_CHARS){ count ++; length += L; } else break; } // lock AGP memory u32 vOffset; FVF::TL* v = (FVF::TL*)RCache.Vertex.Lock (length*4,pGeom.stride(),vOffset); FVF::TL* start = v; // fill vertices u32 last = i+count; for (; i<last; i++) { String &PS = strings[i]; int len = xr_strlen(PS.string); if (len) { float X = float(iFloor(PS.x)); float Y = float(iFloor(PS.y)); float S = PS.height*g_current_font_scale.y; float Y2 = Y+S; switch(PS.align) { case alCenter: X -= ( iFloor(SizeOf_(PS.string,PS.height)*.5f) ) * g_current_font_scale.x; break; case alRight: X -= iFloor(SizeOf_(PS.string,PS.height)); break; } u32 clr,clr2; clr2 = clr = PS.c; if (uFlags&fsGradient){ u32 _R = color_get_R (clr)/2; u32 _G = color_get_G (clr)/2; u32 _B = color_get_B (clr)/2; u32 _A = color_get_A (clr); clr2 = color_rgba (_R,_G,_B,_A); } float tu,tv; for (int j=0; j<len; j++) { int c = GetCharRM (PS.string[j]); Fvector l = GetCharTC (PS.string[j]); float scw = l.z * g_current_font_scale.x; //. float scw = vTS.x * l.z * g_current_font_scale.x; float fTCWidth = l.z/vTS.x; if ((c>=0)&&!fis_zero(l.z)) { tu = l.x/vTS.x;//+vHalfPixel.x; tv = l.y/vTS.y;//+vHalfPixel.y; v->set (X-0.5f, Y2-0.5f, clr2,tu, tv+fTCHeight); v++; v->set (X-0.5f, Y-0.5f, clr, tu, tv); v++; v->set (X+scw-0.5f, Y2-0.5f, clr2,tu+fTCWidth, tv+fTCHeight); v++; v->set (X+scw-0.5f, Y-0.5f, clr, tu+fTCWidth, tv); v++; } X+=scw*vInterval.x; } } } // Unlock and draw u32 vCount = (u32)(v-start); RCache.Vertex.Unlock (vCount,pGeom.stride()); if (vCount){ RCache.set_Geometry (pGeom); RCache.Render (D3DPT_TRIANGLELIST,vOffset,0,vCount,0,vCount/2); } } strings.clear_not_free (); }
u32 CLAItem::CalculateBGR(float T, int& frame) { frame = iFloor(fmodf(T,float(iFrameCount)/fFPS)*fFPS); return InterpolateBGR(frame); }
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; }
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); } }
void SplineBase::computeIndex(float s, int& i, float& u) const { int N = time.size(); debugAssertM(N > 0, "No control points"); float t0 = time[0]; float tn = time[N - 1]; if (N < 2) { // No control points to work with i = 0; u = 0.0; } else if (cyclic) { float fi = getFinalInterval(); // Cyclic spline if ((s < t0) || (s >= tn + fi)) { // Cyclic, off the bottom or top // Compute offset and reduce to the in-bounds case float d = duration(); // Number of times we wrapped around the cyclic array int wraps = iFloor((s - t0) / d); debugAssert(s - d * wraps >= t0); debugAssert(s - d * wraps < tn + getFinalInterval()); computeIndex(s - d * wraps, i, u); i += wraps * N; } else if (s >= tn) { debugAssert(s < tn + fi); // Cyclic, off the top but before the end of the last interval i = N - 1; u = (s - tn) / fi; } else { // Cyclic, in bounds computeIndexInBounds(s, i, u); } } else { // Non-cyclic if (s < t0) { // Non-cyclic, off the bottom. Assume points are spaced // following the first time interval. float dt = time[1] - t0; float x = (s - t0) / dt; i = iFloor(x); u = x - i; } else if (s >= tn) { // Non-cyclic, off the top. Assume points are spaced following // the last time interval. float dt = tn - time[N - 2]; float x = N - 1 + (s - tn) / dt; i = iFloor(x); u = x - i; } else { // In bounds, non-cyclic. Assume a regular // distribution (which gives O(1) for uniform spacing) // and then binary search to handle the general case // efficiently. computeIndexInBounds(s, i, u); } // if in bounds } // if cyclic }
Vector3int32::Vector3int32(const class Vector3& v) { x = (int32)iFloor(v.x + 0.5); y = (int32)iFloor(v.y + 0.5); z = (int32)iFloor(v.z + 0.5); }
// There is no "ParseOFF" because OFF parsing is trivial--it has no subparts or materials, // and is directly an indexed format. void ArticulatedModel::loadOFF(const Specification& specification) { Part* part = addPart(m_name); Geometry* geom = addGeometry("geom"); Mesh* mesh = addMesh("mesh", part, geom); mesh->material = UniversalMaterial::create(); TextInput::Settings s; s.cppBlockComments = false; s.cppLineComments = false; s.otherCommentCharacter = '#'; TextInput ti(specification.filename, s); /////////////////////////////////////////////////////////////// // Parse header std::string header = ti.readSymbol(); bool hasTexCoords = false; bool hasColors = false; bool hasNormals = false; bool hasHomogeneous = false; bool hasHighDimension = false; if (beginsWith(header, "ST")) { hasTexCoords = true; header = header.substr(2); } if (beginsWith(header, "C")) { hasColors = true; header = header.substr(1); } if (beginsWith(header, "N")) { hasNormals = true; header = header.substr(1); } if (beginsWith(header, "4")) { hasHomogeneous = true; header = header.substr(1); } if (beginsWith(header, "n")) { hasHighDimension = true; header = header.substr(1); } geom->cpuVertexArray.hasTexCoord0 = hasTexCoords; geom->cpuVertexArray.hasTangent = false; // Remaining header should be "OFF", but is not required according to the spec Token t = ti.peek(); if ((t.type() == Token::SYMBOL) && (t.string() == "BINARY")) { throw std::string("BINARY OFF files are not supported by this version of G3D::ArticulatedModel"); } int ndim = 3; if (hasHighDimension) { ndim = int(ti.readNumber()); } if (hasHomogeneous) { ++ndim; } if (ndim < 3) { throw std::string("OFF files must contain at least 3 dimensions"); } int nV = iFloor(ti.readNumber()); int nF = iFloor(ti.readNumber()); int nE = iFloor(ti.readNumber()); (void)nE; /////////////////////////////////////////////////// Array<int>& index = mesh->cpuIndexArray; geom->cpuVertexArray.vertex.resize(nV); // Read the per-vertex data for (int v = 0; v < nV; ++v) { CPUVertexArray::Vertex& vertex = geom->cpuVertexArray.vertex[v]; // Position for (int i = 0; i < 3; ++i) { vertex.position[i] = float(ti.readNumber()); } // Ignore higher dimensions for (int i = 3; i < ndim; ++i) { (void)ti.readNumber(); } if (hasNormals) { // Normal (assume always 3 components) for (int i = 0; i < 3; ++i) { vertex.normal[i] = float(ti.readNumber()); } } else { vertex.normal.x = fnan(); } if (hasColors) { // Color (assume always 3 components) for (int i = 0; i < 3; ++i) { ti.readNumber(); } } if (hasTexCoords) { // Texcoords (assume always 2 components) for (int i = 0; i < 2; ++i) { vertex.texCoord0[i] = float(ti.readNumber()); } } // Skip to the end of the line. If the file was corrupt we'll at least get the next vertex right ti.readUntilNewlineAsString(); } // Faces // Convert arbitrary triangle fans to triangles Array<int> poly; for (int i = 0; i < nF; ++i) { poly.fastClear(); int polySize = iFloor(ti.readNumber()); debugAssert(polySize > 2); if (polySize == 3) { // Triangle (common case) for (int j = 0; j < 3; ++j) { index.append(iFloor(ti.readNumber())); } } else { poly.resize(polySize); for (int j = 0; j < polySize; ++j) { poly[j] = iFloor(ti.readNumber()); debugAssertM(poly[j] < nV, "OFF file contained an index greater than the number of vertices."); } // Expand the poly into triangles MeshAlg::toIndexedTriList(poly, PrimitiveType::TRIANGLE_FAN, index); } // Trim to the end of the line, except on the last line of the // file (where it doesn't matter) if (i != nF - 1) { // Ignore per-face colors ti.readUntilNewlineAsString(); } } }
u8 fpackZ (float v) { s32 _v = iFloor (_abs(v)*255.f + .5f); clamp (_v,0,255); return u8(_v); }
Color4uint8::Color4uint8(const class Color4& c) { r = iMin(255, iFloor(c.r * 256)); g = iMin(255, iFloor(c.g * 256)); b = iMin(255, iFloor(c.b * 256)); a = iMin(255, iFloor(c.a * 256)); }
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; }
float CMainWeaponPreference::ffGetValue() { if (ef_storage().non_alife().member()) { #pragma todo("Dima to Dima : Append MainWeaponPreference with non-ALife branch") return (0); } else { CSE_ALifeHumanAbstract *l_tpALifeHumanAbstract = smart_cast<CSE_ALifeHumanAbstract*>(ef_storage().alife().member()); R_ASSERT2 (l_tpALifeHumanAbstract,"Non-human object in EquipmentPreference evaluation function"); return (l_tpALifeHumanAbstract->m_cpMainWeaponPreferences[ef_storage().m_pfMainWeaponType->dwfGetDiscreteValue(iFloor(ef_storage().m_pfMainWeaponType->ffGetMaxResultValue() + .5f))]); } }
u8 fpack (float v) { s32 _v = iFloor (((v+1)*.5f)*255.f + .5f); clamp (_v,0,255); return u8(_v); }
void CLevel::ReculcInterpolationSteps () { lvInterpSteps = iFloor(float(m_dwDeltaUpdate) / (fixed_step*1000)); if (lvInterpSteps > 60) lvInterpSteps = 60; if (lvInterpSteps < 3) lvInterpSteps = 3; };
Vector2int16::Vector2int16(const class Vector2& v) { x = (int16)iFloor(v.x + 0.5); y = (int16)iFloor(v.y + 0.5); }
void CBuild::PreOptimize() { // We use overlapping hash table to avoid boundary conflicts vecVertex* HASH [HDIM_X+1][HDIM_Y+1][HDIM_Z+1]; Fvector VMmin, VMscale, VMeps, scale; // Calculate offset,scale,epsilon Fbox bb = scene_bb; VMscale.set (bb.max.x-bb.min.x, bb.max.y-bb.min.y, bb.max.z-bb.min.z); VMmin.set (bb.min); VMeps.set (VMscale.x/HDIM_X/2,VMscale.y/HDIM_Y/2,VMscale.z/HDIM_Z/2); VMeps.x = (VMeps.x<EPS_L)?VMeps.x:EPS_L; VMeps.y = (VMeps.y<EPS_L)?VMeps.y:EPS_L; VMeps.z = (VMeps.z<EPS_L)?VMeps.z:EPS_L; scale.set (float(HDIM_X),float(HDIM_Y),float(HDIM_Z)); scale.div (VMscale); u32 Vcount = lc_global_data()->g_vertices().size(), Vremoved=0; u32 Fcount = lc_global_data()->g_faces().size(), Fremoved=0; // Pre-alloc memory int _size = (HDIM_X+1)*(HDIM_Y+1)*(HDIM_Z+1); int _average= (Vcount/_size)/2; if (_average<2) _average = 2; { for (int ix=0; ix<HDIM_X+1; ix++) for (int iy=0; iy<HDIM_Y+1; iy++) for (int iz=0; iz<HDIM_Z+1; iz++) { HASH[ix][iy][iz] = new vecVertex(); HASH[ix][iy][iz]->reserve (_average); } } // Status("Processing..."); g_bUnregister = false; for (int it = 0; it<(int)lc_global_data()->g_vertices().size(); it++) { if (0==(it%100000)) { Progress(_sqrt(float(it)/float(lc_global_data()->g_vertices().size()))); Status ("Processing... (%d verts removed)",Vremoved); } if (it>=(int)lc_global_data()->g_vertices().size()) break; Vertex *pTest = lc_global_data()->g_vertices()[it]; Fvector &V = pTest->P; // Hash u32 ix,iy,iz; ix = iFloor ((V.x-VMmin.x)*scale.x); iy = iFloor ((V.y-VMmin.y)*scale.y); iz = iFloor ((V.z-VMmin.z)*scale.z); R_ASSERT (ix<=HDIM_X && iy<=HDIM_Y && iz<=HDIM_Z); vecVertex &H = *(HASH[ix][iy][iz]); // Search similar vertices in hash table for (vecVertexIt T=H.begin(); T!=H.end(); T++) { Vertex *pBase = *T; if (pBase->similar(*pTest,g_params().m_weld_distance)) { while(pTest->m_adjacents.size()) pTest->m_adjacents.front()->VReplace(pTest, pBase); lc_global_data()->destroy_vertex(lc_global_data()->g_vertices()[it]); Vremoved += 1; pTest = NULL; break; } } // If we get here - there is no similar vertices - register in hash tables if (pTest) { H.push_back (pTest); u32 ixE,iyE,izE; ixE = iFloor((V.x+VMeps.x-VMmin.x)*scale.x); iyE = iFloor((V.y+VMeps.y-VMmin.y)*scale.y); izE = iFloor((V.z+VMeps.z-VMmin.z)*scale.z); R_ASSERT(ixE<=HDIM_X && iyE<=HDIM_Y && izE<=HDIM_Z); if (ixE!=ix) HASH[ixE][iy][iz]->push_back (pTest); if (iyE!=iy) HASH[ix][iyE][iz]->push_back (pTest); if (izE!=iz) HASH[ix][iy][izE]->push_back (pTest); if ((ixE!=ix)&&(iyE!=iy)) HASH[ixE][iyE][iz]->push_back (pTest); if ((ixE!=ix)&&(izE!=iz)) HASH[ixE][iy][izE]->push_back (pTest); if ((iyE!=iy)&&(izE!=iz)) HASH[ix][iyE][izE]->push_back (pTest); if ((ixE!=ix)&&(iyE!=iy)&&(izE!=iz)) HASH[ixE][iyE][izE]->push_back (pTest); } } Status("Removing degenerated/duplicated faces..."); g_bUnregister = false; for (u32 it=0; it<lc_global_data()->g_faces().size(); it++) { R_ASSERT (it>=0 && it<(int)lc_global_data()->g_faces().size()); Face* F = lc_global_data()->g_faces()[it]; if ( F->isDegenerated()) { lc_global_data()->destroy_face (lc_global_data()->g_faces()[it]); Fremoved ++; } else { // Check validity F->Verify ( ); } Progress (float(it)/float(lc_global_data()->g_faces().size())); } if (InvalideFaces()) { err_save (); xrDebug::Fatal (DEBUG_INFO,"* FATAL: %d invalid faces. Compilation aborted",InvalideFaces()); } Status ("Adjacency check..."); g_bUnregister = false; for (u32 it = 0; it<lc_global_data()->g_vertices().size(); ++it) { if (lc_global_data()->g_vertices()[it] && (lc_global_data()->g_vertices()[it]->m_adjacents.empty())) { lc_global_data()->destroy_vertex (lc_global_data()->g_vertices()[it]); ++Vremoved; } } Status ("Cleanup..."); lc_global_data()->g_vertices().erase (std::remove(lc_global_data()->g_vertices().begin(),lc_global_data()->g_vertices().end(),(Vertex*)0),lc_global_data()->g_vertices().end()); lc_global_data()->g_faces().erase (std::remove(lc_global_data()->g_faces().begin(),lc_global_data()->g_faces().end(),(Face*)0),lc_global_data()->g_faces().end()); { for (int ix=0; ix<HDIM_X+1; ix++) for (int iy=0; iy<HDIM_Y+1; iy++) for (int iz=0; iz<HDIM_Z+1; iz++) { xr_delete(HASH[ix][iy][iz]); } } mem_Compact (); clMsg("%d vertices removed. (%d left)",Vcount-lc_global_data()->g_vertices().size(),lc_global_data()->g_vertices().size()); clMsg("%d faces removed. (%d left)", Fcount-lc_global_data()->g_faces().size(), lc_global_data()->g_faces().size()); // ------------------------------------------------------------- /* int err_count =0 ; for (int _1=0; _1<g_faces.size(); _1++) { Progress(float(_1)/float(g_faces.size())); for (int _2=0; _2<g_faces.size(); _2++) { if (_1==_2) continue; if (FaceEqual(*g_faces[_1],*g_faces[_2])) { err_count ++; } } } clMsg ("! duplicate/same faces found:%d",err_count); */ // ------------------------------------------------------------- }
IC void i_section (int Sect, BOOL bMiddle) { // Find the start/end Y pixel coord, set the starting pts for scan line ends int startY, endY; float *startp1, *startp2; float E1[3], E2[3]; if (Sect == BOTTOM) { startY = iCeil(currentA[1]); endY = iFloor(currentB[1])-1; startp1 = startp2 = currentA; if (bMiddle) endY ++; // check 'endY' for out-of-triangle int test = iFloor(currentC[1]); if (endY >=test) endY --; // Find the edge differences E1[0] = currentB[0]-currentA[0]; E2[0] = currentC[0]-currentA[0]; E1[1] = currentB[1]-currentA[1]; E2[1] = currentC[1]-currentA[1]; E1[2] = currentB[2]-currentA[2]; E2[2] = currentC[2]-currentA[2]; } else { startY = iCeil(currentB[1]); endY = iFloor(currentC[1]); startp1 = currentA; startp2 = currentB; if (bMiddle) startY --; // check 'startY' for out-of-triangle int test = iCeil(currentA[1]); if (startY < test) startY ++; // Find the edge differences E1[0] = currentC[0]-currentA[0]; E2[0] = currentC[0]-currentB[0]; E1[1] = currentC[1]-currentA[1]; E2[1] = currentC[1]-currentB[1]; E1[2] = currentC[2]-currentA[2]; E2[2] = currentC[2]-currentB[2]; } Vclamp(startY,0,occ_dim); Vclamp(endY, 0,occ_dim); if (startY >= endY) return; // Compute the inverse slopes of the lines, ie rate of change of X by Y float mE1 = E1[0]/E1[1]; float mE2 = E2[0]/E2[1]; // Initial Y offset for left and right (due to pixel rounding) float e1_init_dY = float(startY) - startp1[1], e2_init_dY = float(startY) - startp2[1]; float t,leftX, leftZ, rightX, rightZ, left_dX, right_dX, left_dZ, right_dZ; // find initial values, step values if ( ((mE1<mE2)&&(Sect==BOTTOM)) || ((mE1>mE2)&&(Sect==TOP)) ) { // E1 is on the Left // Initial Starting values for left (from E1) t = e1_init_dY/E1[1]; // Initial fraction of offset leftX = startp1[0] + E1[0]*t; left_dX = mE1; leftZ = startp1[2] + E1[2]*t; left_dZ = E1[2]/E1[1]; // Initial Ending values for right (from E2) t = e2_init_dY/E2[1]; // Initial fraction of offset rightX = startp2[0] + E2[0]*t; right_dX = mE2; rightZ = startp2[2] + E2[2]*t; right_dZ = E2[2]/E2[1]; } else { // E2 is on left // Initial Starting values for left (from E2) t = e2_init_dY/E2[1]; // Initial fraction of offset leftX = startp2[0] + E2[0]*t; left_dX = mE2; leftZ = startp2[2] + E2[2]*t; left_dZ = E2[2]/E2[1]; // Initial Ending values for right (from E1) t = e1_init_dY/E1[1]; // Initial fraction of offset rightX = startp1[0] + E1[0]*t; right_dX = mE1; rightZ = startp1[2] + E1[2]*t; right_dZ = E1[2]/E1[1]; } // Now scan all lines in this section float lhx = left_dX/2; leftX += lhx; // half pixel float rhx = right_dX/2; rightX += rhx; // half pixel for (; startY<=endY; startY++) { i_scan (startY, leftX, lhx, rightX, rhx, leftZ, rightZ); leftX += left_dX; rightX += right_dX; leftZ += left_dZ; rightZ += right_dZ; } }
void dxThunderboltRender::Render(CEffect_Thunderbolt &owner) { VERIFY (owner.current); // lightning model float dv = owner.lightning_phase*0.5f; dv = (owner.lightning_phase>0.5f)?Random.randI(2)*0.5f:dv; RCache.set_CullMode (CULL_NONE); u32 v_offset,i_offset; dxThunderboltDescRender *pThRen = (dxThunderboltDescRender*)&*owner.current->m_pRender; u32 vCount_Lock = pThRen->l_model->number_vertices; u32 iCount_Lock = pThRen->l_model->number_indices; IRender_DetailModel::fvfVertexOut* v_ptr= (IRender_DetailModel::fvfVertexOut*) RCache.Vertex.Lock (vCount_Lock, hGeom_model->vb_stride, v_offset); u16* i_ptr = RCache.Index.Lock (iCount_Lock, i_offset); // XForm verts pThRen->l_model->transfer(owner.current_xform,v_ptr,0xffffffff,i_ptr,0,0.f,dv); // Flush if needed RCache.Vertex.Unlock(vCount_Lock,hGeom_model->vb_stride); RCache.Index.Unlock (iCount_Lock); RCache.set_xform_world(Fidentity); RCache.set_Shader (pThRen->l_model->shader); RCache.set_Geometry (hGeom_model); RCache.Render (D3DPT_TRIANGLELIST,v_offset,0,vCount_Lock,i_offset,iCount_Lock/3); RCache.set_CullMode (CULL_CCW); // gradient Fvector vecSx, vecSy; u32 VS_Offset; FVF::LIT *pv = (FVF::LIT*) RCache.Vertex.Lock(8,hGeom_gradient.stride(),VS_Offset); // top { u32 c_val = iFloor(owner.current->m_GradientTop->fOpacity*owner.lightning_phase*255.f); u32 c = color_rgba(c_val,c_val,c_val,c_val); vecSx.mul (Device.vCameraRight, owner.current->m_GradientTop->fRadius.x*owner.lightning_size); vecSy.mul (Device.vCameraTop, -owner.current->m_GradientTop->fRadius.y*owner.lightning_size); pv->set (owner.current_xform.c.x+vecSx.x-vecSy.x, owner.current_xform.c.y+vecSx.y-vecSy.y, owner.current_xform.c.z+vecSx.z-vecSy.z, c, 0, 0); pv++; pv->set (owner.current_xform.c.x+vecSx.x+vecSy.x, owner.current_xform.c.y+vecSx.y+vecSy.y, owner.current_xform.c.z+vecSx.z+vecSy.z, c, 0, 1); pv++; pv->set (owner.current_xform.c.x-vecSx.x-vecSy.x, owner.current_xform.c.y-vecSx.y-vecSy.y, owner.current_xform.c.z-vecSx.z-vecSy.z, c, 1, 0); pv++; pv->set (owner.current_xform.c.x-vecSx.x+vecSy.x, owner.current_xform.c.y-vecSx.y+vecSy.y, owner.current_xform.c.z-vecSx.z+vecSy.z, c, 1, 1); pv++; } // center { u32 c_val = iFloor(owner.current->m_GradientTop->fOpacity*owner.lightning_phase*255.f); u32 c = color_rgba(c_val,c_val,c_val,c_val); vecSx.mul (Device.vCameraRight, owner.current->m_GradientCenter->fRadius.x*owner.lightning_size); vecSy.mul (Device.vCameraTop, -owner.current->m_GradientCenter->fRadius.y*owner.lightning_size); pv->set (owner.lightning_center.x+vecSx.x-vecSy.x, owner.lightning_center.y+vecSx.y-vecSy.y, owner.lightning_center.z+vecSx.z-vecSy.z, c, 0, 0); pv++; pv->set (owner.lightning_center.x+vecSx.x+vecSy.x, owner.lightning_center.y+vecSx.y+vecSy.y, owner.lightning_center.z+vecSx.z+vecSy.z, c, 0, 1); pv++; pv->set (owner.lightning_center.x-vecSx.x-vecSy.x, owner.lightning_center.y-vecSx.y-vecSy.y, owner.lightning_center.z-vecSx.z-vecSy.z, c, 1, 0); pv++; pv->set (owner.lightning_center.x-vecSx.x+vecSy.x, owner.lightning_center.y-vecSx.y+vecSy.y, owner.lightning_center.z-vecSx.z+vecSy.z, c, 1, 1); pv++; } RCache.Vertex.Unlock (8,hGeom_gradient.stride()); RCache.set_xform_world (Fidentity); RCache.set_Geometry (hGeom_gradient); RCache.set_Shader (((dxFlareRender*)&*owner.current->m_GradientTop->m_pFlare)->hShader); #ifdef USE_DX10 // Hack. Since lightning gradient uses sun shader override z write settings manually RCache.set_Z(TRUE); RCache.set_ZFunc(D3DCMP_LESSEQUAL); #endif // USE_DX10 #ifdef USE_DX10 // Hack. Since lightning gradient uses sun shader override z write settings manually RCache.set_Z(TRUE); RCache.set_ZFunc(D3DCMP_LESSEQUAL); #endif // USE_DX10 RCache.Render (D3DPT_TRIANGLELIST,VS_Offset, 0,4,0,2); RCache.set_Shader (((dxFlareRender*)&*owner.current->m_GradientCenter->m_pFlare)->hShader); #ifdef USE_DX10 // Hack. Since lightning gradient uses sun shader override z write settings manually RCache.set_Z(TRUE); RCache.set_ZFunc(D3DCMP_LESSEQUAL); #endif // USE_DX10 #ifdef USE_DX10 // Hack. Since lightning gradient uses sun shader override z write settings manually RCache.set_Z(TRUE); RCache.set_ZFunc(D3DCMP_LESSEQUAL); #endif // USE_DX10 RCache.Render (D3DPT_TRIANGLELIST,VS_Offset+4, 0,4,0,2); }
// Rasterize a scan line between given X point values, corresponding Z values and current color void i_scan (int curY, float leftX, float lhx, float rightX, float rhx, float startZ, float endZ) { // calculate span(s) float start_c = leftX+lhx; float end_c = rightX+rhx; float startR = leftX-lhx; float endR = rightX-rhx; float startT =startR, endT =end_c; float startX =start_c, endX =endR; if (start_c<startR) {startT = start_c; startX = startR; } if (end_c<endR) {endT = endR; endX = end_c; } // guard-banding and clipping int minT = iFloor(startT)-1, maxT = iCeil(endT)+1; Vclamp (minT,1,occ_dim-1); Vclamp (maxT,1,occ_dim-1); if (minT >= maxT) return; int minX = iCeil(startX), maxX = iFloor(endX); Vclamp (minX,0,occ_dim); Vclamp (maxX,0,occ_dim); int limLeft,limRight; if (minX > maxX) { limLeft=maxX; limRight=minX; } else { limLeft=minX; limRight=maxX; } // interpolate float lenR = endR - startR; float Zlen = endZ - startZ; float Z = startZ + (minT - startR)/lenR * Zlen; // interpolate Z to the start float Zend = startZ + (maxT - startR)/lenR * Zlen; // interpolate Z to the end float dZ = (Zend-Z)/(maxT-minT); // increment in Z / pixel wrt dX // Move to far my dz/5 to place the pixel at the center of face that it covers. // This will make sure that objects will not be clipped for just standing next to the home from outside. Z += 0.5f*_abs(dZ); // gain access to buffers occTri** pFrame = Raster.get_frame(); float* pDepth = Raster.get_depth(); // left connector int i_base = curY*occ_dim; int i = i_base+minT; int limit = i_base+limLeft; for (; i<limit; i++, Z+=dZ) { if (shared(currentTri,pFrame[i-1])) { //float ZR = (Z+2*pDepth[i-1])*one_div_3; if (Z<pDepth[i]) { pFrame[i] = currentTri; pDepth[i] = __max(Z,pDepth[i-1]); dwPixels++; } } } // compute the scanline limit = i_base+maxX; for (; i<limit; i++, Z+=dZ) { if (Z<pDepth[i]) { pFrame[i] = currentTri; pDepth[i] = Z; dwPixels++; } } // right connector i = i_base+maxT-1; limit = i_base+limRight; Z = Zend-dZ; for (; i>=limit; i--, Z-=dZ) { if (shared(currentTri,pFrame[i+1])) { //float ZR = (Z+2*pDepth[i+1])*one_div_3; if (Z<pDepth[i]) { pFrame[i] = currentTri; pDepth[i] = __max(Z,pDepth[i+1]); dwPixels++; } } } }