void transfer(const char *name, xr_vector<T> &dest, IReader& F, u32 chunk) { IReader* O = F.open_chunk(chunk); u32 count = O?(O->length()/sizeof(T)):0; clMsg ("* %16s: %d",name,count); if (count) { dest.reserve(count); dest.insert (dest.begin(), (T*)O->pointer(), (T*)O->pointer() + count); } if (O) O->close (); }
void global_slots_data:: Load ( ) { // Load .details // copy //if() IReader* R = FS.r_open ( "$level$", "build.details" ); R->r_chunk ( 0, &dtH ); R->seek ( 0 ); u32 check_sum = crc32( R-> pointer(), R->length()); recalculation_data.load( check_sum ); if( !recalculation_data.recalculating() ) { IWriter* W = FS.w_open ( "$level$", "level.details" ); W->w ( R->pointer(), R->length() ); FS.w_close ( W ); } FS.r_close ( R ); // re-open string_path N; FS.update_path ( N, "$level$", "level.details" ); dtFS = xr_new<CVirtualFileRW> ( N ); R_ASSERT ( dtH.version()==DETAIL_VERSION ); dtFS->find_chunk ( 2 ); dtS = (DetailSlot*)dtFS->pointer(); }
bool CALifeStorageManager::load (LPCSTR save_name_no_check) { LPCSTR game_saves_path = FS.get_path("$game_saves$")->m_Path; string_path save_name; strncpy_s (save_name, sizeof(save_name), save_name_no_check, sizeof(save_name)-5-xr_strlen(SAVE_EXTENSION)-xr_strlen(game_saves_path)); CTimer timer; timer.Start (); string_path save; xr_strcpy (save,m_save_name); if (!save_name) { if (!xr_strlen(m_save_name)) R_ASSERT2 (false,"There is no file name specified!"); } else { strconcat (sizeof(m_save_name), m_save_name, save_name, SAVE_EXTENSION); } string_path file_name; FS.update_path (file_name,"$game_saves$",m_save_name); xr_strcpy (g_last_saved_game, save_name); xr_strcpy (g_bug_report_file, file_name); IReader *stream; stream = FS.r_open(file_name); if (!stream) { Msg ("* Cannot find saved game %s",file_name); xr_strcpy (m_save_name,save); return (false); } CHECK_OR_EXIT (CSavedGameWrapper::valid_saved_game(*stream),make_string("%s\nSaved game version mismatch or saved game is corrupted",file_name)); /* string512 temp; strconcat (sizeof(temp),temp,CStringTable().translate("st_loading_saved_game").c_str()," \"",save_name,SAVE_EXTENSION,"\""); g_pGamePersistent->LoadTitle(temp); */ g_pGamePersistent->LoadTitle(); unload (); reload (m_section); u32 source_count = stream->r_u32(); void *source_data = xr_malloc(source_count); rtc_decompress (source_data,source_count,stream->pointer(),stream->length() - 3*sizeof(u32)); FS.r_close (stream); load (source_data, source_count, file_name); xr_free (source_data); groups().on_after_game_load (); VERIFY (graph().actor()); Msg ("* Game %s is successfully loaded from file '%s' (%.3fs)",save_name, file_name,timer.GetElapsed_sec()); return (true); }
BOOL testEqual (LPCSTR path, IReader* base) { IReader* test = FS.r_open (path); if (test->length() != base->length()) { return FALSE; } return 0==memcmp(test->pointer(),base->pointer(),base->length()); }
bool xrCompressor::testEqual(LPCSTR path, IReader* base) { bool res = false; IReader* test = FS.r_open (path); if(test->length() == base->length()) { if( 0==memcmp(test->pointer(),base->pointer(),base->length()) ) res = TRUE; } FS.r_close (test); return res; }
CDemoPlay::CDemoPlay(const char *name, float ms, u32 cycles, float life_time) : CEffectorCam(cefDemo,life_time/*,FALSE*/) { Msg ("*** Playing demo: %s",name); Console->Execute ("hud_weapon 0"); if( g_bBenchmark || g_SASH.IsRunning() ) Console->Execute ("hud_draw 0"); fSpeed = ms; dwCyclesLeft = cycles?cycles:1; m_pMotion = 0; m_MParam = 0; string_path nm, fn; xr_strcpy (nm,sizeof(nm),name); LPSTR extp =strext(nm); if (extp) xr_strcpy ( nm, sizeof( nm ) - ( extp - nm ), ".anm"); if ( FS.exist(fn,"$level$",nm) || FS.exist(fn,"$game_anims$",nm) ) { m_pMotion = xr_new<COMotion> (); m_pMotion->LoadMotion (fn); m_MParam = xr_new<SAnimParams> (); m_MParam->Set (m_pMotion); m_MParam->Play (); }else{ if (!FS.exist(name)) { g_pGameLevel->Cameras().RemoveCamEffector (cefDemo); return ; } IReader* fs = FS.r_open (name); u32 sz = fs->length(); if (sz%sizeof(Fmatrix) != 0) { FS.r_close (fs); g_pGameLevel->Cameras().RemoveCamEffector (cefDemo); return ; } seq.resize (sz/sizeof(Fmatrix)); m_count = seq.size(); CopyMemory (&*seq.begin(),fs->pointer(),sz); FS.r_close (fs); Log ("~ Total key-frames: ",m_count); } stat_started = FALSE; Device.PreCache (50, true, false); }
CSavedGameWrapper::CSavedGameWrapper (LPCSTR saved_game_name) { string_path file_name; saved_game_full_name (saved_game_name,file_name); R_ASSERT3 (FS.exist(file_name),"There is no saved game ",file_name); IReader *stream = FS.r_open(file_name); if (!valid_saved_game(*stream)) { FS.r_close (stream); CALifeTimeManager time_manager(alife_section); m_game_time = time_manager.game_time(); m_actor_health = 1.f; m_level_id = ai().game_graph().header().levels().begin()->first; return; } u32 source_count = stream->r_u32(); void *source_data = xr_malloc(source_count); rtc_decompress (source_data,source_count,stream->pointer(),stream->length() - 3*sizeof(u32)); FS.r_close (stream); IReader reader(source_data,source_count); { CALifeTimeManager time_manager(alife_section); time_manager.load (reader); m_game_time = time_manager.game_time(); } { R_ASSERT2 (reader.find_chunk(OBJECT_CHUNK_DATA),"Can't find chunk OBJECT_CHUNK_DATA!"); u32 count = reader.r_u32(); VERIFY (count > 0); CSE_ALifeDynamicObject *object = CALifeObjectRegistry::get_object(reader); VERIFY (object->ID == 0); CSE_ALifeCreatureActor *actor = smart_cast<CSE_ALifeCreatureActor*>(object); VERIFY (actor); m_actor_health = actor->g_Health(); m_level_id = ai().game_graph().vertex(object->m_tGraphID)->level_id(); F_entity_Destroy (object); } xr_free (source_data); }
bool operator ()(char* o){ //compare file names int eq = xr_strcmp(m_full_name,o); if(0!=eq) return false; if( !m_flags.test(eDontCheckFileSize) ){ //compare file size const CLocatorAPI::file* f = m_fs_old->exist("$target_folder$",o); u32 file_size = f->size_real; if ( (f->vfs==0xffffffff) && (file_size != m_file_size) ) return false; }; //compare file crc if( !m_crc32 && !m_flags.test(eDontCheckCRC) ){ IReader* r = m_fs_new->r_open ("$target_folder$",m_full_name); m_crc32 = crc32 (r->pointer(),r->length()); m_fs_new->r_close(r); }; if( !m_flags.test(eDontCheckCRC) ){ IReader* r_ = m_fs_old->r_open("$target_folder$",o); u32 crc32_ = crc32 (r_->pointer(),r_->length()); m_fs_old->r_close(r_); if(m_crc32!=crc32_) return false; } if( !m_flags.test(eDontCheckBinary) ){ //compare files binary content IReader* f1 = m_fs_new->r_open ("$target_folder$",m_full_name); IReader* f2 = m_fs_old->r_open ("$target_folder$",o); int res = memcmp(f1->pointer(),f2->pointer(),f1->length()); m_fs_new->r_close(f1); m_fs_old->r_close(f2); if(0!=res) return false; } return true; }
void CObjectSpace::Load () { IReader *F = FS.r_open ("$level$", "level.cform"); R_ASSERT (F); hdrCFORM H; F->r (&H,sizeof(hdrCFORM)); Fvector* verts = (Fvector*)F->pointer(); CDB::TRI* tris = (CDB::TRI*)(verts+H.vertcount); R_ASSERT (CFORM_CURRENT_VERSION==H.version); Static.build ( verts, H.vertcount, tris, H.facecount, build_callback ); m_BoundingVolume.set (H.aabb); g_SpatialSpace->initialize (H.aabb); g_SpatialSpacePhysic->initialize (H.aabb); Sound->set_geometry_occ ( &Static ); Sound->set_handler ( _sound_event ); FS.r_close (F); }
HRESULT __stdcall Open (D3DXINCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID *ppData, UINT *pBytes) { string_path pname; strconcat (sizeof(pname),pname,::Render->getShaderPath(),pFileName); IReader* R = FS.r_open ("$game_shaders$",pname); if (0==R) { // possibly in shared directory or somewhere else - open directly R = FS.r_open ("$game_shaders$",pFileName); if (0==R) return E_FAIL; } // duplicate and zero-terminate u32 size = R->length(); u8* data = xr_alloc<u8> (size + 1); CopyMemory (data,R->pointer(),size); data[size] = 0; FS.r_close (R); *ppData = data; *pBytes = size; return D3D_OK; }
int ProcessDifference() { LPCSTR params = GetCommandLine(); Flags32 _flags; _flags.zero(); if(strstr(params,"-diff /?")){ printf("HELP:\n"); printf("xrCompress.exe -diff <new_data> <old_data> -out <diff_resulf> [options]\n"); printf("<new_data>, <old_data> and <diff_resulf> values must be a folder name\n"); printf("[options] are set of:\n"); printf("-nofileage do not perform file age checking\n"); printf("-crc do not perform crc32 checking\n"); printf("-nobinary do not perform binary content checking\n"); printf("-nosize do not perform file size checking\n"); return 3; } CLocatorAPI* FS_new = NULL; CLocatorAPI* FS_old = NULL; xr_vector<char*>* file_list_old = NULL; xr_vector<char*>* folder_list_old = NULL; xr_vector<char*>* file_list_new = NULL; xr_vector<char*>* folder_list_new = NULL; sscanf (strstr(params,"-diff ")+6,"%[^ ] ",new_folder); sscanf (strstr(params,"-diff ")+6+xr_strlen(new_folder)+1,"%[^ ] ",old_folder); sscanf (strstr(params,"-out ")+5,"%[^ ] ",target_folder); if(strstr(params,"-nofileage")){ _flags.set(file_comparer::eDontCheckFileAge, TRUE); }; if(strstr(params,"-nocrc")){ _flags.set(file_comparer::eDontCheckCRC, TRUE); }; if(strstr(params,"-nobinary")){ _flags.set(file_comparer::eDontCheckBinary, TRUE); }; if(strstr(params,"-nosize")){ _flags.set(file_comparer::eDontCheckFileSize, TRUE); }; FS_new = xr_new<CLocatorAPI> (); FS_new->_initialize(CLocatorAPI::flTargetFolderOnly,new_folder); file_list_new = FS_new->file_list_open ("$target_folder$",FS_ListFiles); folder_list_new = FS_new->file_list_open ("$target_folder$",FS_ListFolders); FS_old = xr_new<CLocatorAPI> (); FS_old->_initialize(CLocatorAPI::flTargetFolderOnly,old_folder); file_list_old = FS_old->file_list_open ("$target_folder$",FS_ListFiles); folder_list_old = FS_old->file_list_open ("$target_folder$",FS_ListFolders); xr_vector<LPCSTR> target_file_list; target_file_list.reserve(file_list_new->size()); for(u32 i=0; i<file_list_new->size();++i){ file_comparer fc(file_list_new->at(i),FS_new, FS_old,_flags); xr_vector<char*>::iterator it = std::find_if(file_list_old->begin(),file_list_old->end(),fc); if(it != file_list_old->end()){ printf("skip file %s\n",file_list_new->at(i)); }else target_file_list.push_back(file_list_new->at(i)); } string_path out_path; for(u32 i=0; i<target_file_list.size();++i){ LPCSTR fn = target_file_list[i]; strconcat(out_path,target_folder,"\\",fn); VerifyPath(out_path); IReader* r = FS_new->r_open("$target_folder$",fn); IWriter* w = FS_old->w_open(out_path); w->w(r->pointer(),r->length()); FS_new->r_close(r); FS_old->w_close(w); } FS_new->file_list_close(file_list_new); FS_new->file_list_close(folder_list_new); FS_old->file_list_close(file_list_old); FS_old->file_list_close(folder_list_old); xr_delete(FS_new); xr_delete(FS_old); return 0; }
void xrCompressor::CompressOne(LPCSTR path) { filesTOTAL ++; if (testSKIP(path)) { filesSKIP ++; printf (" - a SKIP"); Msg ("%-80s - SKIP",path); return; } string_path fn; strconcat (sizeof(fn), fn, target_name.c_str(), "\\", path); if (::GetFileAttributes(fn)==u32(-1)) { filesSKIP ++; printf (" - CAN'T OPEN"); Msg ("%-80s - CAN'T OPEN",path); return; } IReader* src = FS.r_open (fn); if (0==src) { filesSKIP ++; printf (" - CAN'T OPEN"); Msg ("%-80s - CAN'T OPEN",path); return; } bytesSRC += src->length (); u32 c_crc32 = crc32 (src->pointer(),src->length()); u32 c_ptr = 0; u32 c_size_real = 0; u32 c_size_compressed = 0; u32 a_tests = 0; ALIAS* A = testALIAS (src,c_crc32,a_tests); printf ("%3da ",a_tests); if(A) { filesALIAS ++; printf ("ALIAS"); Msg ("%-80s - ALIAS (%s)",path,A->path); // Alias found c_ptr = A->c_ptr; c_size_real = A->c_size_real; c_size_compressed = A->c_size_compressed; } else { if (testVFS(path)) { filesVFS ++; // Write into BaseFS c_ptr = fs_pack_writer->tell (); c_size_real = src->length(); c_size_compressed = src->length(); fs_pack_writer->w (src->pointer(),c_size_real); printf ("VFS"); Msg ("%-80s - VFS",path); } else { //if(testVFS(path)) // Compress into BaseFS c_ptr = fs_pack_writer->tell(); c_size_real = src->length(); if (0!=c_size_real) { u32 c_size_max = rtc_csize (src->length()); u8* c_data = xr_alloc<u8> (c_size_max); t_compress.Begin (); c_size_compressed = c_size_max; if (bFast) { R_ASSERT(LZO_E_OK == lzo1x_1_compress ((u8*)src->pointer(),c_size_real,c_data,&c_size_compressed,c_heap)); }else { R_ASSERT(LZO_E_OK == lzo1x_999_compress ((u8*)src->pointer(),c_size_real,c_data,&c_size_compressed,c_heap)); } t_compress.End (); if ((c_size_compressed+16) >= c_size_real) { // Failed to compress - revert to VFS filesVFS ++; c_size_compressed = c_size_real; fs_pack_writer->w (src->pointer(),c_size_real); printf ("VFS (R)"); Msg ("%-80s - VFS (R)",path); } else { // Compressed OK - optimize if (!bFast) { u8* c_out = xr_alloc<u8> (c_size_real); u32 c_orig = c_size_real; R_ASSERT (LZO_E_OK == lzo1x_optimize (c_data,c_size_compressed,c_out,&c_orig, NULL)); R_ASSERT (c_orig == c_size_real ); xr_free (c_out); }//bFast fs_pack_writer->w (c_data,c_size_compressed); printf ("%3.1f%%", 100.f*float(c_size_compressed)/float(src->length())); Msg ("%-80s - OK (%3.1f%%)",path,100.f*float(c_size_compressed)/float(src->length())); } // cleanup xr_free (c_data); }else { //0!=c_size_real filesVFS ++; c_size_compressed = c_size_real; printf ("VFS (R)"); Msg ("%-80s - EMPTY FILE",path); } }//test VFS } //(A) // Write description write_file_header (path,c_crc32,c_ptr,c_size_real,c_size_compressed); if (0==A) { // Register for future aliasing ALIAS R; R.path = xr_strdup (fn); R.crc = c_crc32; R.c_ptr = c_ptr; R.c_size_real = c_size_real; R.c_size_compressed = c_size_compressed; aliases.insert (mk_pair(R.c_size_real,R)); } FS.r_close (src); }
//----------------------------------------------------------------------- BOOL motions_value::load (LPCSTR N, IReader *data, vecBones* bones) { m_id = N; bool bRes = true; // Load definitions U16Vec rm_bones (bones->size(),BI_NONE); IReader* MP = data->open_chunk(OGF_S_SMPARAMS); if (MP) { u16 vers = MP->r_u16(); u16 part_bone_cnt = 0; string128 buf; R_ASSERT3 (vers<=xrOGF_SMParamsVersion,"Invalid OGF/OMF version:",N); // partitions u16 part_count; part_count = MP->r_u16(); for (u16 part_i=0; part_i<part_count; part_i++) { CPartDef& PART = m_partition[part_i]; MP->r_stringZ (buf,sizeof(buf)); PART.Name = _strlwr(buf); PART.bones.resize (MP->r_u16()); for (xr_vector<u32>::iterator b_it=PART.bones.begin(); b_it<PART.bones.end(); b_it++) { MP->r_stringZ (buf,sizeof(buf)); u16 m_idx = u16 (MP->r_u32()); *b_it = find_bone_id (bones,buf); #ifdef _EDITOR if (*b_it==BI_NONE ) { bRes = false; Msg ("! Can't find bone: '%s'", buf); } if (rm_bones.size() <= m_idx) { bRes = false; Msg ("! Can't load: '%s' invalid bones count", N); } #else VERIFY3 (*b_it!=BI_NONE,"Can't find bone:", buf); #endif if (bRes) rm_bones[m_idx] = u16(*b_it); } part_bone_cnt = u16(part_bone_cnt + (u16)PART.bones.size()); } #ifdef _EDITOR if (part_bone_cnt!=(u16)bones->size()){ bRes = false; Msg("! Different bone count[%s] [Object: '%d' <-> Motions: '%d']", N, bones->size(),part_bone_cnt); } #else VERIFY3(part_bone_cnt==(u16)bones->size(),"Different bone count '%s'",N); #endif if (bRes) { // motion defs (cycle&fx) u16 mot_count = MP->r_u16(); m_mdefs.resize (mot_count); for (u16 mot_i=0; mot_i<mot_count; mot_i++) { MP->r_stringZ (buf,sizeof(buf)); shared_str nm = _strlwr (buf); u32 dwFlags = MP->r_u32 (); CMotionDef& D = m_mdefs[mot_i]; D.Load (MP,dwFlags,vers); //. m_mdefs.push_back (D); if (dwFlags&esmFX) m_fx.insert (mk_pair(nm,mot_i)); else m_cycle.insert (mk_pair(nm,mot_i)); m_motion_map.insert (mk_pair(nm,mot_i)); } } MP->close(); }else { xrDebug::Fatal (DEBUG_INFO,"Old skinned model version unsupported! (%s)",N); } if (!bRes) return false; // Load animation IReader* MS = data->open_chunk(OGF_S_MOTIONS); if (!MS) return false; u32 dwCNT = 0; MS->r_chunk_safe (0,&dwCNT,sizeof(dwCNT)); VERIFY (dwCNT<0x3FFF); // MotionID 2 bit - slot, 14 bit - motion index // set per bone motion size for (u32 i=0; i<bones->size(); i++) m_motions[bones->at(i)->name].resize(dwCNT); // load motions for (u16 m_idx=0; m_idx<(u16)dwCNT; m_idx++){ string128 mname; R_ASSERT (MS->find_chunk(m_idx+1)); MS->r_stringZ (mname,sizeof(mname)); #ifdef _DEBUG // sanity check xr_strlwr (mname); accel_map::iterator I= m_motion_map.find(mname); VERIFY3 (I!=m_motion_map.end(),"Can't find motion:",mname); VERIFY3 (I->second==m_idx,"Invalid motion index:",mname); #endif u32 dwLen = MS->r_u32(); for (u32 i=0; i<bones->size(); i++){ u16 bone_id = rm_bones[i]; VERIFY2 (bone_id!=BI_NONE,"Invalid remap index."); CMotion& M = m_motions[bones->at(bone_id)->name][m_idx]; M.set_count (dwLen); M.set_flags (MS->r_u8()); if (M.test_flag(flRKeyAbsent)) { CKeyQR* r = (CKeyQR*)MS->pointer(); u32 crc_q = crc32(r,sizeof(CKeyQR)); M._keysR.create (crc_q,1,r); MS->advance (1 * sizeof(CKeyQR)); }else{ u32 crc_q = MS->r_u32 (); M._keysR.create (crc_q,dwLen,(CKeyQR*)MS->pointer()); MS->advance (dwLen * sizeof(CKeyQR)); } if (M.test_flag(flTKeyPresent)) { u32 crc_t = MS->r_u32 (); if(M.test_flag(flTKey16IsBit)) { M._keysT16.create (crc_t,dwLen,(CKeyQT16*)MS->pointer()); MS->advance (dwLen * sizeof(CKeyQT16)); }else { M._keysT8.create (crc_t,dwLen,(CKeyQT8*)MS->pointer()); MS->advance (dwLen * sizeof(CKeyQT8)); }; MS->r_fvector3 (M._sizeT); MS->r_fvector3 (M._initT); }else { MS->r_fvector3 (M._initT); } } } // Msg("Motions %d/%d %4d/%4d/%d, %s",p_cnt,m_cnt, m_load,m_total,m_r,N); MS->close(); return bRes; }
//////////////////////////////////////////////////////////////////////////// // CSE_Abstract //////////////////////////////////////////////////////////////////////////// CSE_Abstract::CSE_Abstract (LPCSTR caSection) { m_editor_flags.zero (); RespawnTime = 0; net_Ready = FALSE; ID = 0xffff; ID_Parent = 0xffff; ID_Phantom = 0xffff; owner = 0; s_gameid = 0; s_RP = 0xFE; // Use supplied coords s_flags.assign (0); s_name = caSection; s_name_replace = 0; //xr_strdup(""); o_Angle.set (0.f,0.f,0.f); o_Position.set (0.f,0.f,0.f); m_bALifeControl = false; m_wVersion = 0; m_script_version = 0; m_tClassID = TEXT2CLSID(pSettings->r_string(caSection,"class")); // m_spawn_probability = 1.f; m_spawn_flags.zero (); m_spawn_flags.set (flSpawnEnabled ,TRUE); m_spawn_flags.set (flSpawnOnSurgeOnly ,TRUE); m_spawn_flags.set (flSpawnSingleItemOnly ,TRUE); m_spawn_flags.set (flSpawnIfDestroyedOnly ,TRUE); m_spawn_flags.set (flSpawnInfiniteCount ,TRUE); // m_max_spawn_count = 1; // m_spawn_control = ""; // m_spawn_count = 0; // m_last_spawn_time = 0; // m_next_spawn_time = 0; // m_min_spawn_interval = 0; // m_max_spawn_interval = 0; m_ini_file = 0; if (pSettings->line_exist(caSection,"custom_data")) { string_path file_name; FS.update_path (file_name,"$game_config$",pSettings->r_string(caSection,"custom_data")); if (!FS.exist(file_name)) { Msg ("! cannot open config file %s",file_name); } else { IReader *reader = FS.r_open(file_name); VERIFY (reader); { int size = reader->length()*sizeof(char); LPSTR temp = (LPSTR)_alloca(size + 1); CopyMemory (temp,reader->pointer(),size); temp[size] = 0; m_ini_string = temp; } FS.r_close (reader); } } #ifndef AI_COMPILER m_script_clsid = object_factory().script_clsid(m_tClassID); #endif client_data.clear (); }
/* ID3DTexture2D* TW_LoadTextureFromTexture ( ID3DTexture2D* t_from, D3DFORMAT& t_dest_fmt, int levels_2_skip, u32& w, u32& h ) { // Calculate levels & dimensions ID3DTexture2D* t_dest = NULL; D3DSURFACE_DESC t_from_desc0 ; R_CHK (t_from->GetLevelDesc (0,&t_from_desc0)); int levels_exist = t_from->GetLevelCount(); int top_width = t_from_desc0.Width; int top_height = t_from_desc0.Height; Reduce (top_width,top_height,levels_exist,levels_2_skip); // Create HW-surface if (D3DX_DEFAULT==t_dest_fmt) t_dest_fmt = t_from_desc0.Format; R_CHK (D3DXCreateTexture( HW.pDevice, top_width,top_height, levels_exist,0,t_dest_fmt, D3DPOOL_MANAGED,&t_dest )); // Copy surfaces & destroy temporary ID3DTexture2D* T_src= t_from; ID3DTexture2D* T_dst= t_dest; int L_src = T_src->GetLevelCount ()-1; int L_dst = T_dst->GetLevelCount ()-1; for (; L_dst>=0; L_src--,L_dst--) { // Get surfaces IDirect3DSurface9 *S_src, *S_dst; R_CHK (T_src->GetSurfaceLevel (L_src,&S_src)); R_CHK (T_dst->GetSurfaceLevel (L_dst,&S_dst)); // Copy R_CHK (D3DXLoadSurfaceFromSurface(S_dst,NULL,NULL,S_src,NULL,NULL,D3DX_FILTER_NONE,0)); // Release surfaces _RELEASE (S_src); _RELEASE (S_dst); } // OK w = top_width; h = top_height; return t_dest; } template <class _It> IC void TW_Iterate_1OP ( ID3DTexture2D* t_dst, ID3DTexture2D* t_src, const _It pred ) { DWORD mips = t_dst->GetLevelCount(); R_ASSERT (mips == t_src->GetLevelCount()); for (DWORD i = 0; i < mips; i++) { D3DLOCKED_RECT Rsrc,Rdst; D3DSURFACE_DESC desc,descS; t_dst->GetLevelDesc (i, &desc); t_src->GetLevelDesc (i, &descS); VERIFY (desc.Format==descS.Format); VERIFY (desc.Format==D3DFMT_A8R8G8B8); t_src->LockRect (i,&Rsrc,0,0); t_dst->LockRect (i,&Rdst,0,0); for (u32 y = 0; y < desc.Height; y++) { for (u32 x = 0; x < desc.Width; x++) { DWORD& pSrc = *(((DWORD*)((BYTE*)Rsrc.pBits + (y * Rsrc.Pitch)))+x); DWORD& pDst = *(((DWORD*)((BYTE*)Rdst.pBits + (y * Rdst.Pitch)))+x); pDst = pred(pDst,pSrc); } } t_dst->UnlockRect (i); t_src->UnlockRect (i); } } template <class _It> IC void TW_Iterate_2OP ( ID3DTexture2D* t_dst, ID3DTexture2D* t_src0, ID3DTexture2D* t_src1, const _It pred ) { DWORD mips = t_dst->GetLevelCount(); R_ASSERT (mips == t_src0->GetLevelCount()); R_ASSERT (mips == t_src1->GetLevelCount()); for (DWORD i = 0; i < mips; i++) { D3DLOCKED_RECT Rsrc0,Rsrc1,Rdst; D3DSURFACE_DESC desc,descS0,descS1; t_dst->GetLevelDesc (i, &desc); t_src0->GetLevelDesc (i, &descS0); t_src1->GetLevelDesc (i, &descS1); VERIFY (desc.Format==descS0.Format); VERIFY (desc.Format==descS1.Format); VERIFY (desc.Format==D3DFMT_A8R8G8B8); t_src0->LockRect (i,&Rsrc0, 0,0); t_src1->LockRect (i,&Rsrc1, 0,0); t_dst->LockRect (i,&Rdst, 0,0); for (u32 y = 0; y < desc.Height; y++) { for (u32 x = 0; x < desc.Width; x++) { DWORD& pSrc0 = *(((DWORD*)((BYTE*)Rsrc0.pBits + (y * Rsrc0.Pitch)))+x); DWORD& pSrc1 = *(((DWORD*)((BYTE*)Rsrc1.pBits + (y * Rsrc1.Pitch)))+x); DWORD& pDst = *(((DWORD*)((BYTE*)Rdst.pBits + (y * Rdst.Pitch)))+x); pDst = pred(pDst,pSrc0,pSrc1); } } t_dst->UnlockRect (i); t_src0->UnlockRect (i); t_src1->UnlockRect (i); } } IC u32 it_gloss_rev (u32 d, u32 s) { return color_rgba ( color_get_A(s), // gloss color_get_B(d), color_get_G(d), color_get_R(d) ); } IC u32 it_gloss_rev_base(u32 d, u32 s) { u32 occ = color_get_A(d)/3; u32 def = 8; u32 gloss = (occ*1+def*3)/4; return color_rgba ( gloss, // gloss color_get_B(d), color_get_G(d), color_get_R(d) ); } IC u32 it_difference (u32 d, u32 orig, u32 ucomp) { return color_rgba( 128+(int(color_get_R(orig))-int(color_get_R(ucomp)))*2, // R-error 128+(int(color_get_G(orig))-int(color_get_G(ucomp)))*2, // G-error 128+(int(color_get_B(orig))-int(color_get_B(ucomp)))*2, // B-error 128+(int(color_get_A(orig))-int(color_get_A(ucomp)))*2 ); // A-error } IC u32 it_height_rev (u32 d, u32 s) { return color_rgba ( color_get_A(d), // diff x color_get_B(d), // diff y color_get_G(d), // diff z color_get_R(s) ); // height } IC u32 it_height_rev_base(u32 d, u32 s) { return color_rgba ( color_get_A(d), // diff x color_get_B(d), // diff y color_get_G(d), // diff z (color_get_R(s)+color_get_G(s)+color_get_B(s))/3 ); // height } */ ID3DBaseTexture* CRender::texture_load(LPCSTR fRName, u32& ret_msize, bool bStaging) { // Moved here just to avoid warning #ifdef USE_DX11 D3DX11_IMAGE_INFO IMG; #else D3DX10_IMAGE_INFO IMG; #endif ZeroMemory(&IMG, sizeof(IMG)); // Staging control static bool bAllowStaging = !strstr(Core.Params,"-no_staging"); bStaging &= bAllowStaging; ID3DBaseTexture* pTexture2D = NULL; //IDirect3DCubeTexture9* pTextureCUBE = NULL; string_path fn; //u32 dwWidth,dwHeight; u32 img_size = 0; int img_loaded_lod = 0; //D3DFORMAT fmt; u32 mip_cnt=u32(-1); // validation R_ASSERT (fRName); R_ASSERT (fRName[0]); // make file name string_path fname; xr_strcpy(fname,fRName); //. andy if (strext(fname)) *strext(fname)=0; fix_texture_name (fname); IReader* S = NULL; if (!FS.exist(fn,"$game_textures$", fname, ".dds") && strstr(fname,"_bump")) goto _BUMP_from_base; if (FS.exist(fn,"$level$", fname, ".dds")) goto _DDS; if (FS.exist(fn,"$game_saves$", fname, ".dds")) goto _DDS; if (FS.exist(fn,"$game_textures$", fname, ".dds")) goto _DDS; #ifdef _EDITOR ELog.Msg(mtError,"Can't find texture '%s'",fname); return 0; #else Msg("! Can't find texture '%s'",fname); R_ASSERT(FS.exist(fn,"$game_textures$", "ed\\ed_not_existing_texture",".dds")); goto _DDS; // Debug.fatal(DEBUG_INFO,"Can't find texture '%s'",fname); #endif _DDS: { // Load and get header S = FS.r_open (fn); #ifdef DEBUG Msg ("* Loaded: %s[%d]",fn,S->length()); #endif // DEBUG img_size = S->length (); R_ASSERT (S); //R_CHK2 (D3DXGetImageInfoFromFileInMemory (S->pointer(),S->length(),&IMG), fn); #ifdef USE_DX11 R_CHK2 (D3DX11GetImageInfoFromMemory(S->pointer(),S->length(), 0, &IMG, 0), fn); #else R_CHK2 (D3DX10GetImageInfoFromMemory(S->pointer(),S->length(), 0, &IMG, 0), fn); #endif //if (IMG.ResourceType == D3DRTYPE_CUBETEXTURE) goto _DDS_CUBE; if (IMG.MiscFlags & D3D_RESOURCE_MISC_TEXTURECUBE) goto _DDS_CUBE; else goto _DDS_2D; _DDS_CUBE: { //R_CHK(D3DXCreateCubeTextureFromFileInMemoryEx( // HW.pDevice, // S->pointer(),S->length(), // D3DX_DEFAULT, // IMG.MipLevels,0, // IMG.Format, // D3DPOOL_MANAGED, // D3DX_DEFAULT, // D3DX_DEFAULT, // 0,&IMG,0, // &pTextureCUBE // )); // Inited to default by provided default constructor #ifdef USE_DX11 D3DX11_IMAGE_LOAD_INFO LoadInfo; #else D3DX10_IMAGE_LOAD_INFO LoadInfo; #endif //LoadInfo.Usage = D3D_USAGE_IMMUTABLE; if (bStaging) { LoadInfo.Usage = D3D_USAGE_STAGING; LoadInfo.BindFlags = 0; LoadInfo.CpuAccessFlags = D3D_CPU_ACCESS_WRITE; } else { LoadInfo.Usage = D3D_USAGE_DEFAULT; LoadInfo.BindFlags = D3D_BIND_SHADER_RESOURCE; } LoadInfo.pSrcInfo = &IMG; #ifdef USE_DX11 R_CHK(D3DX11CreateTextureFromMemory( HW.pDevice, S->pointer(),S->length(), &LoadInfo, 0, &pTexture2D, 0 )); #else R_CHK(D3DX10CreateTextureFromMemory( HW.pDevice, S->pointer(),S->length(), &LoadInfo, 0, &pTexture2D, 0 )); #endif FS.r_close (S); // OK mip_cnt = IMG.MipLevels; ret_msize = calc_texture_size(img_loaded_lod, mip_cnt, img_size); return pTexture2D; } _DDS_2D: { // Check for LMAP and compress if needed strlwr (fn); // Load SYS-MEM-surface, bound to device restrictions //ID3DTexture2D* T_sysmem; //R_CHK2(D3DXCreateTextureFromFileInMemoryEx // ( // HW.pDevice,S->pointer(),S->length(), // D3DX_DEFAULT,D3DX_DEFAULT, // IMG.MipLevels,0, // IMG.Format, // D3DPOOL_SYSTEMMEM, // D3DX_DEFAULT, // D3DX_DEFAULT, // 0,&IMG,0, // &T_sysmem // ), fn); img_loaded_lod = get_texture_load_lod(fn); // Inited to default by provided default constructor #ifdef USE_DX11 D3DX11_IMAGE_LOAD_INFO LoadInfo; #else D3DX10_IMAGE_LOAD_INFO LoadInfo; #endif //LoadInfo.FirstMipLevel = img_loaded_lod; LoadInfo.Width = IMG.Width; LoadInfo.Height = IMG.Height; if (img_loaded_lod) { Reduce(LoadInfo.Width, LoadInfo.Height, IMG.MipLevels, img_loaded_lod); } //LoadInfo.Usage = D3D_USAGE_IMMUTABLE; if (bStaging) { LoadInfo.Usage = D3D_USAGE_STAGING; LoadInfo.BindFlags = 0; LoadInfo.CpuAccessFlags = D3D_CPU_ACCESS_WRITE; } else { LoadInfo.Usage = D3D_USAGE_DEFAULT; LoadInfo.BindFlags = D3D_BIND_SHADER_RESOURCE; } LoadInfo.pSrcInfo = &IMG; #ifdef USE_DX11 R_CHK2(D3DX11CreateTextureFromMemory ( HW.pDevice,S->pointer(),S->length(), &LoadInfo, 0, &pTexture2D, 0 ), fn); #else R_CHK2(D3DX10CreateTextureFromMemory ( HW.pDevice,S->pointer(),S->length(), &LoadInfo, 0, &pTexture2D, 0 ), fn); #endif FS.r_close (S); mip_cnt = IMG.MipLevels; // OK ret_msize = calc_texture_size(img_loaded_lod, mip_cnt, img_size); return pTexture2D; } } _BUMP_from_base: { //Msg ("! auto-generated bump map: %s",fname); Msg ("! Fallback to default bump map: %s",fname); ////////////////// if (strstr(fname,"_bump#")) { R_ASSERT2 (FS.exist(fn,"$game_textures$", "ed\\ed_dummy_bump#", ".dds"), "ed_dummy_bump#"); S = FS.r_open (fn); R_ASSERT2 (S, fn); img_size = S->length (); goto _DDS_2D; } if (strstr(fname,"_bump")) { R_ASSERT2 (FS.exist(fn,"$game_textures$", "ed\\ed_dummy_bump", ".dds"),"ed_dummy_bump"); S = FS.r_open (fn); R_ASSERT2 (S, fn); img_size = S->length (); goto _DDS_2D; } ////////////////// } return 0; }
//-------------------------------------------------------------------------------------------------------------- SVS* CResourceManager::_CreateVS (LPCSTR _name) { string_path name; strcpy_s (name,_name); if (0 == ::Render->m_skinning) strcat(name,"_0"); if (1 == ::Render->m_skinning) strcat(name,"_1"); if (2 == ::Render->m_skinning) strcat(name,"_2"); LPSTR N = LPSTR (name); map_VS::iterator I = m_vs.find (N); if (I!=m_vs.end()) return I->second; else { SVS* _vs = xr_new<SVS> (); _vs->dwFlags |= xr_resource_flagged::RF_REGISTERED; m_vs.insert (mk_pair(_vs->set_name(name),_vs)); if (0==stricmp(_name,"null")) { _vs->vs = NULL; return _vs; } includer Includer; LPD3DXBUFFER pShaderBuf = NULL; LPD3DXBUFFER pErrorBuf = NULL; LPD3DXSHADER_CONSTANTTABLE pConstants = NULL; HRESULT _hr = S_OK; string_path cname; strconcat (sizeof(cname),cname,::Render->getShaderPath(),_name,".vs"); FS.update_path (cname, "$game_shaders$", cname); // LPCSTR target = NULL; IReader* fs = FS.r_open(cname); R_ASSERT3 (fs, "shader file doesnt exist", cname); // Select target LPCSTR c_target = "vs_2_0"; LPCSTR c_entry = "main"; /*if (HW.Caps.geometry.dwVersion>=CAP_VERSION(3,0)) target="vs_3_0"; else*/ if (HW.Caps.geometry_major>=2) c_target="vs_2_0"; else c_target="vs_1_1"; LPSTR pfs = xr_alloc<char>(fs->length() + 1); strncpy (pfs, (LPCSTR)fs->pointer(), fs->length()); pfs [fs->length()] = 0; if (strstr(pfs, "main_vs_1_1")) { c_target = "vs_1_1"; c_entry = "main_vs_1_1"; } if (strstr(pfs, "main_vs_2_0")) { c_target = "vs_2_0"; c_entry = "main_vs_2_0"; } xr_free(pfs); // vertex R_ASSERT2 (fs,cname); _hr = ::Render->shader_compile(name,LPCSTR(fs->pointer()),fs->length(), NULL, &Includer, c_entry, c_target, D3DXSHADER_DEBUG | D3DXSHADER_PACKMATRIX_ROWMAJOR /*| D3DXSHADER_PREFER_FLOW_CONTROL*/, &pShaderBuf, &pErrorBuf, NULL); // _hr = D3DXCompileShader (LPCSTR(fs->pointer()),fs->length(), NULL, &Includer, "main", target, D3DXSHADER_DEBUG | D3DXSHADER_PACKMATRIX_ROWMAJOR, &pShaderBuf, &pErrorBuf, NULL); FS.r_close (fs); if (SUCCEEDED(_hr)) { if (pShaderBuf) { _hr = HW.pDevice->CreateVertexShader ((DWORD*)pShaderBuf->GetBufferPointer(), &_vs->vs); if (SUCCEEDED(_hr)) { LPCVOID data = NULL; _hr = D3DXFindShaderComment ((DWORD*)pShaderBuf->GetBufferPointer(),MAKEFOURCC('C','T','A','B'),&data,NULL); if (SUCCEEDED(_hr) && data) { pConstants = LPD3DXSHADER_CONSTANTTABLE(data); _vs->constants.parse (pConstants,0x2); } else _hr = E_FAIL; } } else _hr = E_FAIL; } else { VERIFY (pErrorBuf); Log ("! error: ",(LPCSTR)pErrorBuf->GetBufferPointer()); } _RELEASE (pShaderBuf); _RELEASE (pErrorBuf); pConstants = NULL; R_CHK (_hr); return _vs; } }
HRESULT CRender::shader_compile ( LPCSTR name, DWORD const* pSrcData, UINT SrcDataLen, LPCSTR pFunctionName, LPCSTR pTarget, DWORD Flags, void*& result ) { D3DXMACRO defines [128]; int def_it = 0; char sh_name[MAX_PATH] = ""; u32 len = 0; // options if (o.forceskinw) { defines[def_it].Name = "SKIN_COLOR"; defines[def_it].Definition = "1"; def_it ++; } sh_name[len]='0'+char(o.forceskinw); ++len; if (m_skinning<0) { defines[def_it].Name = "SKIN_NONE"; defines[def_it].Definition = "1"; def_it ++; sh_name[len]='1'; ++len; } else { sh_name[len]='0'; ++len; } if (0==m_skinning) { defines[def_it].Name = "SKIN_0"; defines[def_it].Definition = "1"; def_it ++; } sh_name[len]='0'+char(0==m_skinning); ++len; if (1==m_skinning) { defines[def_it].Name = "SKIN_1"; defines[def_it].Definition = "1"; def_it ++; } sh_name[len]='0'+char(1==m_skinning); ++len; if (2==m_skinning) { defines[def_it].Name = "SKIN_2"; defines[def_it].Definition = "1"; def_it ++; } sh_name[len]='0'+char(2==m_skinning); ++len; if (3==m_skinning) { defines[def_it].Name = "SKIN_3"; defines[def_it].Definition = "1"; def_it ++; } sh_name[len]='0'+char(3==m_skinning); ++len; if (4==m_skinning) { defines[def_it].Name = "SKIN_4"; defines[def_it].Definition = "1"; def_it ++; } sh_name[len]='0'+char(4==m_skinning); ++len; // finish defines[def_it].Name = 0; defines[def_it].Definition = 0; def_it ++; R_ASSERT (def_it<128); HRESULT _result = E_FAIL; string_path folder_name, folder; xr_strcpy ( folder, "r1\\objects\\r1\\" ); xr_strcat ( folder, name ); xr_strcat ( folder, "." ); char extension[3]; strncpy_s ( extension, pTarget, 2 ); xr_strcat ( folder, extension ); FS.update_path ( folder_name, "$game_shaders$", folder ); xr_strcat ( folder_name, "\\" ); m_file_set.clear( ); FS.file_list ( m_file_set, folder_name, FS_ListFiles | FS_RootOnly, "*"); string_path temp_file_name, file_name; if ( !match_shader_id(name, sh_name, m_file_set, temp_file_name) ) { string_path file; xr_strcpy ( file, "shaders_cache\\r1\\" ); xr_strcat ( file, name ); xr_strcat ( file, "." ); xr_strcat ( file, extension ); xr_strcat ( file, "\\" ); xr_strcat ( file, sh_name ); FS.update_path ( file_name, "$app_data_root$", file); } else { xr_strcpy ( file_name, folder_name ); xr_strcat ( file_name, temp_file_name ); } if (FS.exist(file_name)) { IReader* file = FS.r_open(file_name); if (file->length()>4) { u32 crc = 0; crc = file->r_u32(); boost::crc_32_type processor; processor.process_block ( file->pointer(), ((char*)file->pointer()) + file->elapsed() ); u32 const real_crc = processor.checksum( ); if ( real_crc == crc ) { _result = create_shader(pTarget, (DWORD*)file->pointer(), file->elapsed(), file_name, result, o.disasm); } } file->close(); } if (FAILED(_result)) { includer Includer; LPD3DXBUFFER pShaderBuf = NULL; LPD3DXBUFFER pErrorBuf = NULL; LPD3DXCONSTANTTABLE pConstants = NULL; LPD3DXINCLUDE pInclude = (LPD3DXINCLUDE)&Includer; _result = D3DXCompileShader((LPCSTR)pSrcData,SrcDataLen,defines,pInclude,pFunctionName,pTarget,Flags|D3DXSHADER_USE_LEGACY_D3DX9_31_DLL,&pShaderBuf,&pErrorBuf,&pConstants); if (SUCCEEDED(_result)) { IWriter* file = FS.w_open(file_name); boost::crc_32_type processor; processor.process_block ( pShaderBuf->GetBufferPointer(), ((char*)pShaderBuf->GetBufferPointer()) + pShaderBuf->GetBufferSize() ); u32 const crc = processor.checksum( ); file->w_u32 (crc); file->w ( pShaderBuf->GetBufferPointer(), (u32)pShaderBuf->GetBufferSize()); FS.w_close (file); _result = create_shader(pTarget, (DWORD*)pShaderBuf->GetBufferPointer(), pShaderBuf->GetBufferSize(), file_name, result, o.disasm); } else { Log ("! ", file_name); if ( pErrorBuf ) Log ("! error: ",(LPCSTR)pErrorBuf->GetBufferPointer()); else Msg ("Can't compile shader hr=0x%08x", _result); } } return _result; }
void global_claculation_data::xrLoad() { string_path N; FS.update_path ( N, "$game_data$", "shaders_xrlc.xr" ); g_shaders_xrlc = new Shader_xrLC_LIB(); g_shaders_xrlc->Load ( N ); // Load CFORM { FS.update_path (N,"$level$","build.cform"); IReader* fs = FS.r_open("$level$","build.cform"); R_ASSERT (fs->find_chunk(0)); hdrCFORM H; fs->r (&H,sizeof(hdrCFORM)); R_ASSERT (CFORM_CURRENT_VERSION==H.version); Fvector* verts = (Fvector*)fs->pointer(); CDB::TRI* tris = (CDB::TRI*)(verts+H.vertcount); RCAST_Model.build ( verts, H.vertcount, tris, H.facecount ); Msg("* Level CFORM: %dK",RCAST_Model.memory()/1024); g_rc_faces.resize (H.facecount); R_ASSERT(fs->find_chunk(1)); fs->r (&*g_rc_faces.begin(),g_rc_faces.size()*sizeof(b_rc_face)); LevelBB.set (H.aabb); } { slots_data.Load( ); } // Lights { IReader* fs = FS.r_open("$level$","build.lights"); IReader* F; u32 cnt; R_Light* L; // rgb F = fs->open_chunk (0); cnt = F->length()/sizeof(R_Light); L = (R_Light*)F->pointer(); g_lights.rgb.assign (L,L+cnt); F->close (); // hemi F = fs->open_chunk (1); cnt = F->length()/sizeof(R_Light); L = (R_Light*)F->pointer(); g_lights.hemi.assign(L,L+cnt); F->close (); // sun F = fs->open_chunk (2); cnt = F->length()/sizeof(R_Light); L = (R_Light*)F->pointer(); g_lights.sun.assign (L,L+cnt); F->close (); FS.r_close (fs); } // Load level data { IReader* fs = FS.r_open ("$level$","build.prj"); IReader* F; // Version u32 version; fs->r_chunk (EB_Version,&version); R_ASSERT(XRCL_CURRENT_VERSION==version); // Header fs->r_chunk (EB_Parameters,&g_params); // Load level data transfer("materials", g_materials, *fs, EB_Materials); transfer("shaders_xrlc",g_shader_compile, *fs, EB_Shaders_Compile); post_process_materials( *g_shaders_xrlc, g_shader_compile, g_materials ); // process textures #ifdef DEBUG xr_vector<b_texture> dbg_textures; #endif Status ("Processing textures..."); { Surface_Init (); F = fs->open_chunk (EB_Textures); u32 tex_count = F->length()/sizeof(b_texture); for (u32 t=0; t<tex_count; t++) { Progress (float(t)/float(tex_count)); b_texture TEX; F->r (&TEX,sizeof(TEX)); #ifdef DEBUG dbg_textures.push_back( TEX ); #endif b_BuildTexture BT; CopyMemory (&BT,&TEX,sizeof(TEX)); // load thumbnail LPSTR N = BT.name; if (strchr(N,'.')) *(strchr(N,'.')) = 0; strlwr (N); if (0==xr_strcmp(N,"level_lods")) { // HACK for merged lod textures BT.dwWidth = 1024; BT.dwHeight = 1024; BT.bHasAlpha= TRUE; BT.pSurface = 0; } else { strcat (N,".thm"); IReader* THM = FS.r_open("$game_textures$",N); R_ASSERT2 (THM, N); // version u32 version = 0; R_ASSERT (THM->r_chunk(THM_CHUNK_VERSION,&version)); // if( version!=THM_CURRENT_VERSION ) FATAL ("Unsupported version of THM file."); // analyze thumbnail information R_ASSERT(THM->find_chunk(THM_CHUNK_TEXTUREPARAM)); THM->r (&BT.THM.fmt,sizeof(STextureParams::ETFormat)); BT.THM.flags.assign (THM->r_u32()); BT.THM.border_color = THM->r_u32(); BT.THM.fade_color = THM->r_u32(); BT.THM.fade_amount = THM->r_u32(); BT.THM.mip_filter = THM->r_u32(); BT.THM.width = THM->r_u32(); BT.THM.height = THM->r_u32(); BOOL bLOD=FALSE; if (N[0]=='l' && N[1]=='o' && N[2]=='d' && N[3]=='\\') bLOD = TRUE; // load surface if it has an alpha channel or has "implicit lighting" flag BT.dwWidth = BT.THM.width; BT.dwHeight = BT.THM.height; BT.bHasAlpha = BT.THM.HasAlphaChannel(); BT.pSurface = 0; if (!bLOD) { if (BT.bHasAlpha || BT.THM.flags.test(STextureParams::flImplicitLighted)) { clMsg ("- loading: %s",N); u32 w=0, h=0; BT.pSurface = Surface_Load(N,w,h); R_ASSERT2 (BT.pSurface,"Can't load surface"); if ((w != BT.dwWidth) || (h != BT.dwHeight)) Msg ("! THM doesn't correspond to the texture: %dx%d -> %dx%d", BT.dwWidth, BT.dwHeight, w, h); BT.Vflip (); } else { // Free surface memory } } } // save all the stuff we've created g_textures.push_back (BT); } } } }
//-------------------------------------------------------------------------------------------------------------- SPS* CResourceManager::_CreatePS (LPCSTR name) { LPSTR N = LPSTR(name); map_PS::iterator I = m_ps.find (N); if (I!=m_ps.end()) return I->second; else { SPS* _ps = xr_new<SPS> (); _ps->dwFlags |= xr_resource_flagged::RF_REGISTERED; m_ps.insert (mk_pair(_ps->set_name(name),_ps)); if (0==stricmp(name,"null")) { _ps->ps = NULL; return _ps; } // Open file includer Includer; string_path cname; strconcat (sizeof(cname), cname,::Render->getShaderPath(),name,".ps"); FS.update_path (cname, "$game_shaders$", cname); // duplicate and zero-terminate IReader* R = FS.r_open(cname); R_ASSERT2 (R,cname); u32 size = R->length(); char* data = xr_alloc<char>(size + 1); CopyMemory (data,R->pointer(),size); data[size] = 0; FS.r_close (R); // Select target LPCSTR c_target = "ps_2_0"; LPCSTR c_entry = "main"; if (strstr(data,"main_ps_1_1")) { c_target = "ps_1_1"; c_entry = "main_ps_1_1"; } if (strstr(data,"main_ps_1_2")) { c_target = "ps_1_2"; c_entry = "main_ps_1_2"; } if (strstr(data,"main_ps_1_3")) { c_target = "ps_1_3"; c_entry = "main_ps_1_3"; } if (strstr(data,"main_ps_1_4")) { c_target = "ps_1_4"; c_entry = "main_ps_1_4"; } if (strstr(data,"main_ps_2_0")) { c_target = "ps_2_0"; c_entry = "main_ps_2_0"; } // Compile LPD3DXBUFFER pShaderBuf = NULL; LPD3DXBUFFER pErrorBuf = NULL; LPD3DXSHADER_CONSTANTTABLE pConstants = NULL; HRESULT _hr = S_OK; _hr = ::Render->shader_compile (name,data,size, NULL, &Includer, c_entry, c_target, D3DXSHADER_DEBUG | D3DXSHADER_PACKMATRIX_ROWMAJOR /*| D3DXSHADER_PREFER_FLOW_CONTROL*/, &pShaderBuf, &pErrorBuf, NULL); //_hr = D3DXCompileShader (text,text_size, NULL, &Includer, c_entry, c_target, D3DXSHADER_DEBUG | D3DXSHADER_PACKMATRIX_ROWMAJOR, &pShaderBuf, &pErrorBuf, NULL); xr_free (data); LPCSTR last_error = ""; if (SUCCEEDED(_hr)) { if (pShaderBuf) { _hr = HW.pDevice->CreatePixelShader ((DWORD*)pShaderBuf->GetBufferPointer(), &_ps->ps); if (SUCCEEDED(_hr)) { LPCVOID data = NULL; _hr = D3DXFindShaderComment ((DWORD*)pShaderBuf->GetBufferPointer(),MAKEFOURCC('C','T','A','B'),&data,NULL); if (SUCCEEDED(_hr) && data) { pConstants = LPD3DXSHADER_CONSTANTTABLE(data); _ps->constants.parse (pConstants,0x1); } else _hr = E_FAIL; } } else _hr = E_FAIL; }else { if (pErrorBuf) last_error = (LPCSTR)pErrorBuf->GetBufferPointer(); } // Real Wolf.10.12.2014 string1024 buff; if (FAILED(_hr)) { if (xr_strlen(last_error)) sprintf_s(buff, 1023, "ќшибка компил¤ции шейдера %s: %s ", name, last_error); else sprintf_s(buff, 1023, "ќшибка компил¤ции шейдера %s. ¬озможна ошибка в скрипте, или\n видеокарта не поддерживает пиксельные шейдеры 1.1", name); Msg(buff); } pConstants = NULL; _RELEASE(pShaderBuf); _RELEASE(pErrorBuf); CHECK_OR_EXIT ( !FAILED(_hr), make_string(buff) ); return _ps; } }
void xrLoad(LPCSTR name, bool draft_mode) { FS.get_path ("$level$")->_set ((LPSTR)name); string256 N; if (!draft_mode) { // shaders string_path N; FS.update_path (N,"$game_data$","shaders_xrlc.xr"); g_shaders_xrlc = xr_new<Shader_xrLC_LIB> (); g_shaders_xrlc->Load (N); // Load CFORM { strconcat (sizeof(N),N,name,"build.cform"); IReader* fs = FS.r_open(N); R_ASSERT (fs->find_chunk(0)); hdrCFORM H; fs->r (&H,sizeof(hdrCFORM)); R_ASSERT (CFORM_CURRENT_VERSION==H.version); Fvector* verts = (Fvector*)fs->pointer(); CDB::TRI* tris = (CDB::TRI*)(verts+H.vertcount); Level.build ( verts, H.vertcount, tris, H.facecount ); Level.syncronize (); Msg("* Level CFORM: %dK",Level.memory()/1024); g_rc_faces.resize (H.facecount); R_ASSERT(fs->find_chunk(1)); fs->r (&*g_rc_faces.begin(),g_rc_faces.size()*sizeof(b_rc_face)); LevelBB.set (H.aabb); FS.r_close (fs); } // Load level data { strconcat (sizeof(N),N,name,"build.prj"); IReader* fs = FS.r_open (N); IReader* F; // Version u32 version; fs->r_chunk (EB_Version,&version); R_ASSERT (XRCL_CURRENT_VERSION >= 17); R_ASSERT (XRCL_CURRENT_VERSION <= 18); // Header b_params Params; fs->r_chunk (EB_Parameters,&Params); // Load level data transfer("materials", g_materials, *fs, EB_Materials); transfer("shaders_xrlc",g_shader_compile, *fs, EB_Shaders_Compile); // process textures Status ("Processing textures..."); { Surface_Init (); F = fs->open_chunk (EB_Textures); u32 tex_count = F->length()/sizeof(b_texture); for (u32 t=0; t<tex_count; t++) { Progress (float(t)/float(tex_count)); b_texture TEX; F->r (&TEX,sizeof(TEX)); b_BuildTexture BT; CopyMemory (&BT,&TEX,sizeof(TEX)); // load thumbnail string128 &N = BT.name; LPSTR extension = strext(N); if (extension) *extension = 0; xr_strlwr (N); if (0==xr_strcmp(N,"level_lods")) { // HACK for merged lod textures BT.dwWidth = 1024; BT.dwHeight = 1024; BT.bHasAlpha= TRUE; BT.pSurface = 0; } else { xr_strcat (N,".thm"); IReader* THM = FS.r_open("$game_textures$",N); // if (!THM) continue; R_ASSERT2 (THM, N); // version u32 version = 0; R_ASSERT (THM->r_chunk(THM_CHUNK_VERSION,&version)); // if( version!=THM_CURRENT_VERSION ) FATAL ("Unsupported version of THM file."); // analyze thumbnail information R_ASSERT(THM->find_chunk(THM_CHUNK_TEXTUREPARAM)); THM->r (&BT.THM.fmt,sizeof(STextureParams::ETFormat)); BT.THM.flags.assign (THM->r_u32()); BT.THM.border_color = THM->r_u32(); BT.THM.fade_color = THM->r_u32(); BT.THM.fade_amount = THM->r_u32(); BT.THM.mip_filter = THM->r_u32(); BT.THM.width = THM->r_u32(); BT.THM.height = THM->r_u32(); BOOL bLOD=FALSE; if (N[0]=='l' && N[1]=='o' && N[2]=='d' && N[3]=='\\') bLOD = TRUE; // load surface if it has an alpha channel or has "implicit lighting" flag BT.dwWidth = BT.THM.width; BT.dwHeight = BT.THM.height; BT.bHasAlpha = BT.THM.HasAlphaChannel(); BT.pSurface = 0; if (!bLOD) { if (BT.bHasAlpha || BT.THM.flags.test(STextureParams::flImplicitLighted)) { clMsg ("- loading: %s",N); u32 w=0, h=0; BT.pSurface = Surface_Load(N,w,h); R_ASSERT2 (BT.pSurface,"Can't load surface"); if ((w != BT.dwWidth) || (h != BT.dwHeight)) Msg ("! THM doesn't correspond to the texture: %dx%d -> %dx%d", BT.dwWidth, BT.dwHeight, w, h); BT.Vflip (); } else { // Free surface memory } } } // save all the stuff we've created g_textures.push_back (BT); } } } } // // Load emitters // { // strconcat (N,name,"level.game"); // IReader *F = FS.r_open(N); // IReader *O = 0; // if (0!=(O = F->open_chunk (AIPOINT_CHUNK))) { // for (int id=0; O->find_chunk(id); id++) { // Emitters.push_back(Fvector()); // O->r_fvector3 (Emitters.back()); // } // O->close(); // } // } // // Load lights { strconcat (sizeof(N),N,name,"build.prj"); IReader* F = FS.r_open(N); R_ASSERT2 (F,"There is no file 'build.prj'!"); IReader &fs= *F; // Version u32 version; fs.r_chunk (EB_Version,&version); R_ASSERT (XRCL_CURRENT_VERSION >= 17); R_ASSERT (XRCL_CURRENT_VERSION <= 18); // Header b_params Params; fs.r_chunk (EB_Parameters,&Params); // Lights (Static) { F = fs.open_chunk(EB_Light_static); b_light_static temp; u32 cnt = F->length()/sizeof(temp); for (u32 i=0; i<cnt; i++) { R_Light RL; F->r (&temp,sizeof(temp)); Flight& L = temp.data; if (_abs(L.range) > 10000.f) { Msg ("! BAD light range : %f",L.range); L.range = L.range > 0.f ? 10000.f : -10000.f; } // type if (L.type == D3DLIGHT_DIRECTIONAL) RL.type = LT_DIRECT; else RL.type = LT_POINT; // generic properties RL.position.set (L.position); RL.direction.normalize_safe (L.direction); RL.range = L.range*1.1f; RL.range2 = RL.range*RL.range; RL.attenuation0 = L.attenuation0; RL.attenuation1 = L.attenuation1; RL.attenuation2 = L.attenuation2; RL.amount = L.diffuse.magnitude_rgb (); RL.tri[0].set (0,0,0); RL.tri[1].set (0,0,0); RL.tri[2].set (0,0,0); // place into layer if (0==temp.controller_ID) g_lights.push_back (RL); } F->close (); } } // Init params // g_params.Init (); // Load initial map from the Level Editor { string_path file_name; strconcat (sizeof(file_name),file_name,name,"build.aimap"); IReader *F = FS.r_open(file_name); R_ASSERT2 (F, file_name); R_ASSERT (F->open_chunk(E_AIMAP_CHUNK_VERSION)); R_ASSERT (F->r_u16() == E_AIMAP_VERSION); R_ASSERT (F->open_chunk(E_AIMAP_CHUNK_BOX)); F->r (&LevelBB,sizeof(LevelBB)); R_ASSERT (F->open_chunk(E_AIMAP_CHUNK_PARAMS)); F->r (&g_params,sizeof(g_params)); R_ASSERT (F->open_chunk(E_AIMAP_CHUNK_NODES)); u32 N = F->r_u32(); R_ASSERT2 (N < ((u32(1) << u32(MAX_NODE_BIT_COUNT)) - 2),"Too many nodes!"); g_nodes.resize (N); hdrNODES H; H.version = XRAI_CURRENT_VERSION; H.count = N+1; H.size = g_params.fPatchSize; H.size_y = 1.f; H.aabb = LevelBB; typedef BYTE NodeLink[3]; for (u32 i=0; i<N; i++) { NodeLink id; u16 pl; SNodePositionOld _np; NodePosition np; for (int j=0; j<4; ++j) { F->r (&id,3); g_nodes[i].n[j] = (*LPDWORD(&id)) & 0x00ffffff; } pl = F->r_u16(); pvDecompress (g_nodes[i].Plane.n,pl); F->r (&_np,sizeof(_np)); CNodePositionConverter(_np,H,np); g_nodes[i].Pos = vertex_position(np,LevelBB,g_params); g_nodes[i].Plane.build(g_nodes[i].Pos,g_nodes[i].Plane.n); } F->close (); if (!strstr(Core.Params,"-keep_temp_files")) DeleteFile (file_name); } }
void CRender::level_Load(IReader* fs) { R_ASSERT (0!=g_pGameLevel); R_ASSERT (!b_loaded); // Begin pApp->LoadBegin (); dxRenderDeviceRender::Instance().Resources->DeferredLoad (TRUE); IReader* chunk; // Shaders // g_pGamePersistent->LoadTitle ("st_loading_shaders"); g_pGamePersistent->LoadTitle (); { chunk = fs->open_chunk (fsL_SHADERS); R_ASSERT2 (chunk,"Level doesn't builded correctly."); u32 count = chunk->r_u32 (); Shaders.resize (count); for(u32 i=0; i<count; i++) // skip first shader as "reserved" one { string512 n_sh,n_tlist; LPCSTR n = LPCSTR(chunk->pointer()); chunk->skip_stringZ (); if (0==n[0]) continue; xr_strcpy (n_sh,n); LPSTR delim = strchr(n_sh,'/'); *delim = 0; xr_strcpy (n_tlist,delim+1); Shaders[i] = dxRenderDeviceRender::Instance().Resources->Create(n_sh,n_tlist); } chunk->close(); } // Components Wallmarks = xr_new<CWallmarksEngine> (); Details = xr_new<CDetailManager> (); if (!g_dedicated_server) { // VB,IB,SWI // g_pGamePersistent->LoadTitle("st_loading_geometry"); g_pGamePersistent->LoadTitle(); { CStreamReader *geom = FS.rs_open("$level$","level.geom"); R_ASSERT2 (geom, "level.geom"); LoadBuffers (geom,FALSE); LoadSWIs (geom); FS.r_close (geom); } //...and alternate/fast geometry { CStreamReader *geom = FS.rs_open("$level$","level.geomx"); R_ASSERT2 (geom, "level.geomX"); LoadBuffers (geom,TRUE); FS.r_close (geom); } // Visuals // g_pGamePersistent->LoadTitle("st_loading_spatial_db"); g_pGamePersistent->LoadTitle(); chunk = fs->open_chunk(fsL_VISUALS); LoadVisuals (chunk); chunk->close (); // Details // g_pGamePersistent->LoadTitle("st_loading_details"); g_pGamePersistent->LoadTitle(); Details->Load (); } // Sectors // g_pGamePersistent->LoadTitle("st_loading_sectors_portals"); g_pGamePersistent->LoadTitle(); LoadSectors (fs); // 3D Fluid Load3DFluid (); // HOM HOM.Load (); // Lights // pApp->LoadTitle ("Loading lights..."); LoadLights (fs); // End pApp->LoadEnd (); // sanity-clear lstLODs.clear (); lstLODgroups.clear (); mapLOD.clear (); // signal loaded b_loaded = TRUE ; }
ID3DBaseTexture* CRender::texture_load(LPCSTR fRName, u32& ret_msize) { ID3DTexture2D* pTexture2D = NULL; IDirect3DCubeTexture9* pTextureCUBE = NULL; string_path fn; u32 dwWidth,dwHeight; u32 img_size = 0; int img_loaded_lod = 0; D3DFORMAT fmt; u32 mip_cnt=u32(-1); // validation R_ASSERT (fRName); R_ASSERT (fRName[0]); // make file name string_path fname; xr_strcpy(fname,fRName); //. andy if (strext(fname)) *strext(fname)=0; fix_texture_name (fname); IReader* S = NULL; //if (FS.exist(fn,"$game_textures$",fname, ".dds") && strstr(fname,"_bump")) goto _BUMP; if (!FS.exist(fn,"$game_textures$", fname, ".dds") && strstr(fname,"_bump")) goto _BUMP_from_base; if (FS.exist(fn,"$level$", fname, ".dds")) goto _DDS; if (FS.exist(fn,"$game_saves$", fname, ".dds")) goto _DDS; if (FS.exist(fn,"$game_textures$", fname, ".dds")) goto _DDS; #ifdef _EDITOR ELog.Msg(mtError,"Can't find texture '%s'",fname); return 0; #else Msg("! Can't find texture '%s'",fname); R_ASSERT(FS.exist(fn,"$game_textures$", "ed\\ed_not_existing_texture",".dds")); goto _DDS; // Debug.fatal(DEBUG_INFO,"Can't find texture '%s'",fname); #endif _DDS: { // Load and get header D3DXIMAGE_INFO IMG; S = FS.r_open (fn); #ifdef DEBUG Msg ("* Loaded: %s[%d]b",fn,S->length()); #endif // DEBUG img_size = S->length (); R_ASSERT (S); HRESULT const result = D3DXGetImageInfoFromFileInMemory (S->pointer(),S->length(),&IMG); if ( FAILED(result) ) { Msg ("! Can't get image info for texture '%s'",fn); FS.r_close (S); string_path temp; R_ASSERT ( FS.exist( temp, "$game_textures$", "ed\\ed_not_existing_texture", ".dds" ) ); R_ASSERT ( xr_strcmp(temp,fn) ); xr_strcpy ( fn, temp ); goto _DDS; } if (IMG.ResourceType == D3DRTYPE_CUBETEXTURE) goto _DDS_CUBE; else goto _DDS_2D; _DDS_CUBE: { HRESULT const result = D3DXCreateCubeTextureFromFileInMemoryEx( HW.pDevice, S->pointer(),S->length(), D3DX_DEFAULT, IMG.MipLevels,0, IMG.Format, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0,&IMG,0, &pTextureCUBE ); FS.r_close (S); if ( FAILED(result) ) { Msg ("! Can't load texture '%s'",fn); string_path temp; R_ASSERT ( FS.exist( temp, "$game_textures$", "ed\\ed_not_existing_texture", ".dds" ) ); R_ASSERT ( xr_strcmp(temp,fn) ); xr_strcpy ( fn, temp ); goto _DDS; } // OK dwWidth = IMG.Width; dwHeight = IMG.Height; fmt = IMG.Format; ret_msize = calc_texture_size(img_loaded_lod, mip_cnt, img_size); mip_cnt = pTextureCUBE->GetLevelCount(); return pTextureCUBE; } _DDS_2D: { strlwr (fn); // Load SYS-MEM-surface, bound to device restrictions ID3DTexture2D* T_sysmem; HRESULT const result = D3DXCreateTextureFromFileInMemoryEx( HW.pDevice,S->pointer(),S->length(), D3DX_DEFAULT,D3DX_DEFAULT, IMG.MipLevels,0, IMG.Format, D3DPOOL_SYSTEMMEM, D3DX_DEFAULT, D3DX_DEFAULT, 0,&IMG,0, &T_sysmem ); FS.r_close (S); if ( FAILED(result) ) { Msg ("! Can't load texture '%s'",fn); string_path temp; R_ASSERT ( FS.exist( temp, "$game_textures$", "ed\\ed_not_existing_texture", ".dds" ) ); strlwr (temp); R_ASSERT ( xr_strcmp(temp,fn) ); xr_strcpy ( fn, temp ); goto _DDS; } img_loaded_lod = get_texture_load_lod(fn); pTexture2D = TW_LoadTextureFromTexture(T_sysmem,IMG.Format, img_loaded_lod, dwWidth, dwHeight); mip_cnt = pTexture2D->GetLevelCount(); _RELEASE (T_sysmem); // OK fmt = IMG.Format; ret_msize = calc_texture_size(img_loaded_lod, mip_cnt, img_size); return pTexture2D; } } /* _BUMP: { // Load SYS-MEM-surface, bound to device restrictions D3DXIMAGE_INFO IMG; IReader* S = FS.r_open (fn); msize = S->length (); ID3DTexture2D* T_height_gloss; R_CHK(D3DXCreateTextureFromFileInMemoryEx( HW.pDevice, S->pointer(),S->length(), D3DX_DEFAULT,D3DX_DEFAULT, D3DX_DEFAULT,0,D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, D3DX_DEFAULT,D3DX_DEFAULT, 0,&IMG,0,&T_height_gloss )); FS.r_close (S); //TW_Save (T_height_gloss,fname,"debug-0","original"); // Create HW-surface, compute normal map ID3DTexture2D* T_normal_1 = 0; R_CHK(D3DXCreateTexture (HW.pDevice,IMG.Width,IMG.Height,D3DX_DEFAULT,0,D3DFMT_A8R8G8B8,D3DPOOL_SYSTEMMEM,&T_normal_1)); R_CHK(D3DXComputeNormalMap (T_normal_1,T_height_gloss,0,0,D3DX_CHANNEL_RED,_BUMPHEIGH)); //TW_Save (T_normal_1,fname,"debug-1","normal"); // Transfer gloss-map TW_Iterate_1OP (T_normal_1,T_height_gloss,it_gloss_rev); //TW_Save (T_normal_1,fname,"debug-2","normal-G"); // Compress fmt = D3DFMT_DXT5; ID3DTexture2D* T_normal_1C = TW_LoadTextureFromTexture(T_normal_1,fmt,psTextureLOD,dwWidth,dwHeight); //TW_Save (T_normal_1C,fname,"debug-3","normal-G-C"); #if RENDER==R_R2 // Decompress (back) fmt = D3DFMT_A8R8G8B8; ID3DTexture2D* T_normal_1U = TW_LoadTextureFromTexture(T_normal_1C,fmt,0,dwWidth,dwHeight); // TW_Save (T_normal_1U,fname,"debug-4","normal-G-CU"); // Calculate difference ID3DTexture2D* T_normal_1D = 0; R_CHK(D3DXCreateTexture(HW.pDevice,dwWidth,dwHeight,T_normal_1U->GetLevelCount(),0,D3DFMT_A8R8G8B8,D3DPOOL_SYSTEMMEM,&T_normal_1D)); TW_Iterate_2OP (T_normal_1D,T_normal_1,T_normal_1U,it_difference); // TW_Save (T_normal_1D,fname,"debug-5","normal-G-diff"); // Reverse channels back + transfer heightmap TW_Iterate_1OP (T_normal_1D,T_height_gloss,it_height_rev); // TW_Save (T_normal_1D,fname,"debug-6","normal-G-diff-H"); // Compress fmt = D3DFMT_DXT5; ID3DTexture2D* T_normal_2C = TW_LoadTextureFromTexture(T_normal_1D,fmt,0,dwWidth,dwHeight); // TW_Save (T_normal_2C,fname,"debug-7","normal-G-diff-H-C"); _RELEASE (T_normal_1U ); _RELEASE (T_normal_1D ); // string256 fnameB; strconcat (fnameB,"$user$",fname,"X"); ref_texture t_temp = dxRenderDeviceRender::Instance().Resources->_CreateTexture (fnameB); t_temp->surface_set (T_normal_2C ); _RELEASE (T_normal_2C ); // texture should keep reference to it by itself #endif // release and return // T_normal_1C - normal.gloss, reversed // T_normal_2C - 2*error.height, non-reversed _RELEASE (T_height_gloss ); _RELEASE (T_normal_1 ); return T_normal_1C; } */ _BUMP_from_base: { Msg ("! auto-generated bump map: %s",fname); ////////////////// #ifndef _EDITOR if (strstr(fname,"_bump#")) { R_ASSERT2 (FS.exist(fn,"$game_textures$", "ed\\ed_dummy_bump#", ".dds"), "ed_dummy_bump#"); S = FS.r_open (fn); R_ASSERT2 (S, fn); img_size = S->length (); goto _DDS_2D; } if (strstr(fname,"_bump")) { R_ASSERT2 (FS.exist(fn,"$game_textures$", "ed\\ed_dummy_bump", ".dds"),"ed_dummy_bump"); S = FS.r_open (fn); R_ASSERT2 (S, fn); img_size = S->length (); goto _DDS_2D; } #endif ////////////////// *strstr (fname,"_bump") = 0; R_ASSERT2 (FS.exist(fn,"$game_textures$", fname, ".dds"),fname); // Load SYS-MEM-surface, bound to device restrictions D3DXIMAGE_INFO IMG; S = FS.r_open (fn); img_size = S->length (); ID3DTexture2D* T_base; R_CHK2(D3DXCreateTextureFromFileInMemoryEx( HW.pDevice, S->pointer(),S->length(), D3DX_DEFAULT,D3DX_DEFAULT, D3DX_DEFAULT,0,D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, D3DX_DEFAULT,D3DX_DEFAULT, 0,&IMG,0,&T_base ), fn); FS.r_close (S); // Create HW-surface ID3DTexture2D* T_normal_1 = 0; R_CHK(D3DXCreateTexture (HW.pDevice,IMG.Width,IMG.Height,D3DX_DEFAULT,0,D3DFMT_A8R8G8B8,D3DPOOL_SYSTEMMEM, &T_normal_1)); R_CHK(D3DXComputeNormalMap (T_normal_1,T_base,0,D3DX_NORMALMAP_COMPUTE_OCCLUSION,D3DX_CHANNEL_LUMINANCE,_BUMPHEIGH)); // Transfer gloss-map TW_Iterate_1OP (T_normal_1,T_base,it_gloss_rev_base); // Compress fmt = D3DFMT_DXT5; img_loaded_lod = get_texture_load_lod(fn); ID3DTexture2D* T_normal_1C = TW_LoadTextureFromTexture(T_normal_1, fmt, img_loaded_lod, dwWidth, dwHeight); mip_cnt = T_normal_1C->GetLevelCount(); #if RENDER==R_R2 // Decompress (back) fmt = D3DFMT_A8R8G8B8; ID3DTexture2D* T_normal_1U = TW_LoadTextureFromTexture(T_normal_1C,fmt,0,dwWidth,dwHeight); // Calculate difference ID3DTexture2D* T_normal_1D = 0; R_CHK(D3DXCreateTexture(HW.pDevice,dwWidth,dwHeight,T_normal_1U->GetLevelCount(),0,D3DFMT_A8R8G8B8,D3DPOOL_SYSTEMMEM,&T_normal_1D)); TW_Iterate_2OP (T_normal_1D,T_normal_1,T_normal_1U,it_difference); // Reverse channels back + transfer heightmap TW_Iterate_1OP (T_normal_1D,T_base,it_height_rev_base); // Compress fmt = D3DFMT_DXT5; ID3DTexture2D* T_normal_2C = TW_LoadTextureFromTexture(T_normal_1D,fmt,0,dwWidth,dwHeight); _RELEASE (T_normal_1U ); _RELEASE (T_normal_1D ); // string256 fnameB; strconcat (sizeof(fnameB),fnameB,"$user$",fname,"_bumpX"); ref_texture t_temp = dxRenderDeviceRender::Instance().Resources->_CreateTexture (fnameB); t_temp->surface_set (T_normal_2C ); _RELEASE (T_normal_2C ); // texture should keep reference to it by itself #endif // T_normal_1C - normal.gloss, reversed // T_normal_2C - 2*error.height, non-reversed _RELEASE (T_base); _RELEASE (T_normal_1); ret_msize = calc_texture_size(img_loaded_lod, mip_cnt, img_size); return T_normal_1C; } }