因此,我的目標是創建一個自包含文件,其中包含要加載到3D場景中的所有資源。例如,將會有一個文本文件詳細說明模型的所有位置,旋轉,比例等,然後是內置模型和紋理的文件夾。這在文件夾中並不難,但爲了簡單起見,我想將它全部放到一個文件中,避免壓縮並解壓縮。我不想壓縮和解壓縮它的原因是爲了加快加載時間,因爲這是針對遊戲的。將文件夾變爲單個文件而不壓縮它?
是否有任何可能的方式來做到這一點?或者我將不得不咬住子彈並將其製成拉鍊。
謝謝。
因此,我的目標是創建一個自包含文件,其中包含要加載到3D場景中的所有資源。例如,將會有一個文本文件詳細說明模型的所有位置,旋轉,比例等,然後是內置模型和紋理的文件夾。這在文件夾中並不難,但爲了簡單起見,我想將它全部放到一個文件中,避免壓縮並解壓縮。我不想壓縮和解壓縮它的原因是爲了加快加載時間,因爲這是針對遊戲的。將文件夾變爲單個文件而不壓縮它?
是否有任何可能的方式來做到這一點?或者我將不得不咬住子彈並將其製成拉鍊。
謝謝。
您可以使用ZIP無壓縮或TAR。但是這裏有一個更好的主意:壓縮它。 CPU時間很便宜。磁盤傳輸需要永久。大多數情況下,加載壓縮數據並解壓縮比加載未壓縮數據更快。
所以你說加載壓縮文件,然後解壓縮它會比保持壓縮更快? – BlueSpud 2014-12-04 00:34:18
是的,使用某些快速算法,特別是具有非常高壓縮比的3D模型。 – 2014-12-04 00:36:12
@BlueSpud根據您的硬盤和CPU,可能(和AdrianMaire所說的壓縮算法一樣)。較慢的硬盤和較快的CPU會增加效益。另一方面,固態硬盤和Raspi ... – deviantfan 2014-12-04 00:36:26
您可以創建一個沒有壓縮的ZIP文件。 (「存儲」模式)。還有類似的包裝歸檔器,可用於從多個文件創建單個歸檔。 * nix系統上的TAR文件非常受歡迎,並且還有許多其他文件。
此外,平衡,將是花解壓縮對抗將用於從磁盤裝載的(未壓縮)文件的時間量的時間量。很多時候,未壓縮文件的磁盤讀取時間比加載壓縮文件並將其解壓縮到內存中的時間要長。
如果這是一個Windows應用程序,你可以使用用戶定義的資源語句在.rc文件爲您的EXE或DLL包含(一個或多個),將來自外部文件作爲二進制資源插入數據。如果您只想分發一個依賴其他文件中包含的數據的EXE文件,或者不想讓您的應用程序可以通過以下方式進行存檔和發佈的文件,那麼這對於您的應用程序可訪問/可修改(無需工作)最終用戶。
這是非常簡單的 - 語法只是
nameID typeID filename
的資源文件。您可以使用::FindResource()
和::LoadResource().
訪問數據用戶定義資源的MS文檔位於http://msdn.microsoft.com/en-us/library/windows/desktop/aa381054(v=vs.85).aspx。
不幸的是,這是在Linux Mac和Windows,所以我有一個項目,不想讓3個項目改變它們。 – BlueSpud 2014-12-04 01:04:52
原始質詢的定時可以是偶然的。事實證明,將來我所建議的查找/加載資源方法對我們來說也不會是我們的選擇(我以前使用它的代碼是跨平臺的),所以我想出了一個解決方案,它也可能爲你工作。儘管你可以很快做出一個你自己的快速版本,但完整的代碼可以作爲一個SO回答發佈(但請參閱我的後續評論)。
基本上,我寫了一個工具,只是需要一個基本名稱爲輸出文件爲argv[1]
(「輸出基本名」),並argv[2...(argc-1)]
輸入文件。我打開output-base-name.cpp
和output-base-name.h
進行書寫(如果它們存在,將覆蓋)。
對於每個輸入文件中,生成器實用程序執行此:
1:基於所述文件名的變量名友好標識符(「 generated_name」)
2:讀取輸入文件
3:轉儲到下列output-base-name.cpp
:
static uint8_t generated_name[] = {
// Initialize with contents of input file as a bunch of 0xNN, 0xNN... values.
};
並進入output-base-name.h
,相應
static const unsigned IDR_generated_name = N; // start at 0, see below re:range check
4:最後輸入文件後,完成了output-base-name.cpp
喜歡的東西
static struct {
unsigned ID;
unsigned size; // I assume you aren't trying to embed files >4GB!
const uint8_t* data;
}
fileData[] = {
// one array element for each input file
{ IDR_generated_name, sizeof(generated_name), generated_name },
...
};
const uint8_t* getResourceData(unsigned ID){
// a real version would do a safer lookup/range check of some sort based on ID
return fileData[ID].data;
}
unsigned getResourceSize(unsigned ID){
// a real version would do a safer lookup/range check of some sort based on ID
return fileData[ID].size;
}
5:飾面output-base-name.h
與原型無論你的 「獲取」 功能的模樣,例如
extern const uint8_t* getResourceData(unsigned ID);
extern unsigned getResourceSize(unsigned ID);
只需使用output-base-name.h
你需要的地方訪問數據,並添加output-base-name.cpp
到你的makefile或項目(使其依賴於二進制輸入文件,使用構建規則的生成工具和make
會自動生成它的你必要時)。如果你想讓它們處於某種動態庫中,只需將適當的導出屬性添加到你的「get」函數中即可。
有發電機包裹你的輸出在一個命名空間,如果你想基於類的接口拼湊到它(或產生一個,而不是如「獲取」功能),你應該是好的。
這種方法比使用未壓縮的壓縮文件(甚至我建議爲Windows目標嵌入的資源的方法)幾個優點:
這僅是我所使用的方法的一個例子,但它涵蓋了所有的基礎知識,所以如果一個解決方案儘快而不是遲一點(再次看到評論)對你更好,這可能就足夠了(你想要在「get」函數中進行範圍檢查 - 至少在調試版本中,也許使用某種類型的容器而不是使用c-style結構數組等)。
在回答(第1部分)中引用的後續評論: 雖然完整的源代碼不會在回覆中發佈(對於長度+在meta post中討論的其他原因[此處](http://meta.stackoverflow.com/questions/278616/提供後續鏈接爲答案)),我幾乎完成了一個將作爲開源發佈的完整實現。我將在城外待上幾天,但我會清理,完成併爲我的快速骯髒/概念驗證版本添加更多功能,並在我返回時發佈到我的博客上。 – frasnian 2014-12-07 08:00:37
後續第2部分(太長時間只有一個): 當我發佈它時,我將刪除這些評論並在答案中添加一個鏈接到源位置,因此如果任何人對全部源感興趣,只需「最喜歡的「當我發佈鏈接時(可能距離現在一週左右),您的個人資料中的原始問題和您的收藏夾標籤將會突出顯示。 – frasnian 2014-12-07 08:01:26
a)Zip不需要壓縮。 b)Zip,7z,Tar,Bzip2等等。有很多這樣的格式。 c)你總是可以製作自己的二進制文件格式。 d)除了在b中提到的一般存檔格式之外,還有一些已建立的專用3D模型文件格式(以及用於保存/加載它們的庫)... – deviantfan 2014-12-04 00:30:38
無論您使用什麼,如果您將按需加載資源,你想要一個有索引的檔案格式。 Zip確實;焦油不。這意味着你必須尋找所有的地方纔能發現你擁有的資源和位置。 – cdhowie 2014-12-04 00:41:55
@cdhowie基於大家都說過的話,我想我會用低壓縮zip。 – BlueSpud 2014-12-04 00:42:55