9

デバイスの RAM の量に基づいて調整したい、テクスチャが重い OpenGL ゲームがあります。私が持っている最高解像度のテクスチャは iPhone 4 または iPad2 で問題なく動作しますが、それ以前のデバイスではテクスチャのロード中にクラッシュします。これらのテクスチャの低解像度バージョンがありますが、それらをいつ使用するかを知る必要があります。

私の現在の戦術は、特定の古いデバイス (3GS には低解像度の画面があり、iPad にはカメラがありません) を検出し、iPad2 以降と iPhone 4 以降の高解像度テクスチャのみをロードすることです。 iPod touchのために何かをしてください。しかし、モデル検出は API やハードウェアの将来の変更に対して脆弱であるため、デバイス モデルをハード コーディングするよりも機能検出を使用したいと考えています。

私が検討しているもう 1 つの可能性は、最初に高解像度のテクスチャをロードしてから、メモリ不足の警告が表示された瞬間にそれらをドロップして低解像度に置き換えることです。ただし、返信する機会があるかどうかはわかりません。デバッグ コンソールに通知が表示される前にアプリが停止することがよくあります。

実行しているデバイスにテクスチャの高解像度バージョンをロードするための十分な RAM がないかどうかを確認するにはどうすればよいですか?

一歩下がって、OpenGL テクスチャ メモリに固有の、使用できる他の適応技術はありますか?

ノート:

  1. 利用可能なRAMの検出に関連する回答をオンとオフでSOで検索しましたが、基本的にはすべて、メモリ使用量をプロファイリングし、無駄を排除することをお勧めします(一時メモリの寿命とそのすべてを最小限に抑えます)。できる限り多くのことを行いましたが、高解像度のテクスチャを古いデバイスに押し込む方法はありません。

  2. PVRTC はオプションではありません。テクスチャには、フラグメント シェーダーで使用されるデータが含まれており、ロスレス形式で保存する必要があります。

4

4 に答える 4

11

デバイスの合計 (最大) 物理 RAM を取得するには、 を使用します[NSProcessInfo processInfo].physicalMemory

ドキュメントを参照してください。

于 2013-10-02T15:46:54.997 に答える
7

合計物理RAMはsysctl()このブログ投稿に記載されているように、を介して利用でき、ここでクリーンなAPIとして実装されています(totalMemory対応する.mファイルのの実装を参照してください)。

利便性と後世のためにブログのコードを削除しました。

#include <sys/sysctl.h>

size_t phys_mem()
{
 int mib[] = { CTL_HW, HW_PHYSMEM };
 size_t mem;
 size_t len = sizeof(mem);
 sysctl(mib, 2, &mem, &len, NULL, 0);
 return mem;
}

sysctl()Appleがこの方法で使用するアプリを承認するかどうかはわかりません。文書化されていますが、MacOSXのみです。

于 2011-11-09T21:55:44.697 に答える
2

この場合のメモリ管理について知っておく必要がある最も重要な考え方は、高解像度テクスチャと低解像度テクスチャのどちらを使用するかということです。私が使用する最も簡単な方法は、これを確認することです

CGFloat scale = [[UIScreen mainScreen] scale];
if ((scale > 1.0) || (self.view.frame.size.width > 320)) {
        highRes = TRUE;
}

これは、これまでのところすべてのデバイスで機能し、将来的には証明されるはずです。新しいデバイスは高解像度を使用します。アスペクト比をすぐに計算することもできます(後でiPadとiPhoneで役立ちます)

aspect = self.view.frame.size.width/self.view.frame.size.width

最初に高解像度をロードしないでください。アプリのロード時間がかかります。私の 3G では、スタートアップのほとんどが (低解像度であっても) テクスチャのロードに費やされます。最初にこれをテストし、高解像度のものには触れないでください。

古いデバイスでは、大きなテクスチャが原因でプログラムが警告なしに終了します。これは、デバッガーがビデオ メモリの消費をトラップできず、それ自体が終了することに関係している可能性があります。

より優れた最適化を行うには、ミップマップに色合いを付けて、実際に使用されている最小のテクスチャ サイズを確認することを検討してください (3D オブジェクトを使用している場合のみ)。

ビデオ RAM サイズの問題は忘れてください。メモリは実際には共有されているため、システム メモリをめぐって競合しています。古いデバイスでは、使用に MB 制限がありましたが、それでもシステム メモリです。

メモリ管理については、多くの方法があります。最も簡単な方法は、読み込まれているテクスチャと必要なテクスチャをマークすることです。メモリの警告が表示されたら、読み込まれているが必要でないテクスチャをダンプします...

于 2011-11-09T10:39:42.487 に答える
0

私が知っている限り、人ができる最も重要な3つのことは -

  1. iOS が警告 1 と 2 を送信したときに実装- (void)didReceiveMemoryWarningして応答します。
  2. Instruments のコードをプロファイリングして、リークを見つけ、最適な実装方法を見つけようとします。
  3. デバイスの種類を検出し、おそらくその情報を使用します。
  4. スペースを節約するために、PVRTC などの何らかの形式のテクスチャ圧縮を使用します。

ほとんどのことをやっていると思います。問題は、iOS デバイスに搭載されている RAM の量を正確に把握していないことです。Apple は、iOS デバイスの技術仕様を公開していません。

また、たとえば 100 MB の消費後にのみメモリ警告が表示されるとは限りません。iOS が表示する警告は、デバイスの現在の状態、実行中の他のアプリ、それらが消費しているメモリの量によって異なります。だからトリッキーになる。

必ず読むべき 2 つのセクションを提案できます -テクスチャ データを操作するためのベスト プラクティスとOpenGL ES アプリケーションの調整

于 2011-11-07T04:21:17.690 に答える