NDS開発::グラフィック
DSのグラフィックの構成はかなり複雑で色々な設定に出来ます.様々なモードを駆使することで,比較的低スペックなDSでも高度な表現が可能です.設定に使うレジスタがとても多いので,ここで全ては説明できていません.
使えるリソース
- 2つのスクリーン(解像度は256x192)
- メインとサブの2つのグラフィックエンジン
- A~Iの9つのVRAMエリア
主に,上記3つのものを自由に組み合わせて使うことが出来ます.
スクリーン
DSには画面が2つあります.画面自体はどちらも同じように使えますが,下の画面はタッチパネルになっています.
グラフィックエンジン(Core)
2つのグラフィックエンジンを搭載しています.微妙に色々と違いがありますが,大きな違いは3Dが扱えるのはメインの方だけになっています.
3Dを使わないなら,どちらのスクリーンをメインにしても,支障ないと思います.
各コアはバックグラウンド(BG)と呼ばれるBG0~BG3の4つの領域を扱えます.レイヤーのように重ねたり,アルファブレンドもできるようです.
0~6のモードがあり,それぞれ4つのBGの扱いが異なります.加えて,フレームバッファモードがあり,これはメモリの内容をそのまま表示します.3Dモードの場合は,MainのBG0が3D用のエリアとなります.
メインのBGに使うメモリは0x6000000~で,サブの方は0x6200000です.用意されているのはアドレス空間だけなので,下で説明するVRAMを割り当てる必要があります.
Mode 0(テキスト)
BG | Main | Sub |
0 | タイル | タイル |
1 | タイル | タイル |
2 | タイル | タイル |
3 | タイル | タイル |
Mode 1(テキスト+回転)
イメージを回転して表示できます.
BG | Main | Sub |
0 | タイル | タイル |
1 | タイル | タイル |
2 | タイル | タイル |
3 | 回転 | 回転 |
Mode 2(テキスト+回転x2)
BG | Main | Sub |
0 | タイル | タイル |
1 | タイル | タイル |
2 | 回転 | 回転 |
3 | 回転 | 回転 |
Mode 3(テキスト+拡張回転)
VRAM上のイメージを回転,スケーリング,オフセット指定して表示できます.このモードは便利.
BG | Main | Sub |
0 | タイル | タイル |
1 | タイル | タイル |
2 | タイル | タイル |
3 | 拡張回転 | 拡張回転 |
Mode 4(テキスト+回転+拡張回転)
BG | Main | Sub |
0 | タイル | タイル |
1 | タイル | タイル |
2 | 回転 | 回転 |
3 | 拡張回転 | 拡張回転 |
Mode 5(テキスト+拡張回転x2)
BG | Main | Sub |
0 | タイル | タイル |
1 | タイル | タイル |
2 | 拡張回転 | 拡張回転 |
3 | 拡張回転 | 拡張回転 |
Mode 6(大きなビットマップ)
MainのBG2で大きなビットマップを扱えるようです(?)
3Dモード
3Dモードでは,MainのBG0で3Dが使えるようになります.OpenGLに良く似たAPIが用意されているようです.
VRAMエリア(Bank)
VRAMとして使えるメモリのエリアは9個あります.単純に9枚のVRAMが確保できるわけではなくて,サイズや使える用途が異なります.
エリア | サイズ | アドレス |
VRAM_A | 128KB | 0x06800000 |
VRAM_B | 128KB | 0x06820000 |
VRAM_C | 128KB | 0x06840000 |
VRAM_D | 128KB | 0x06860000 |
VRAM_E | 64KB | 0x06880000 |
VRAM_F | 16KB | 0x06890000 |
VRAM_G | 16KB | 0x06894000 |
VRAM_H | 32KB | 0x06898000 |
VRAM_I | 16KB | 0x068A0000 |
というような構成です.
さらに,これらのVRAMをどのように使うかの設定も色々あります.必要に応じて,1つのコアに複数のVRAMを割り当てたり出来ます.基本的に,E~Iはスプライトとパレットに使うようです.
A~Dはビットマップを格納できますが,サブ側に設定できるのがCしか無いような……どういうこと?
libndsの関数
lcdSwap()
画面に対応付けられているグラフィックエンジンを切り替える.デフォルトでは,上の画面がメインになっている.関数を呼び出すと,上下の画面の内容が入れ替わります.
videoSetMode(),videoSetModeSub()
グラフィックエンジンのモードを指定します.同時にアクティブにして使用するBGも設定します.
例:videoSetMode(MODE_3_2D | DISPLAY_BG2_ACTIVE | DISPLAY_BG3_ACTIVE);
vramSetBankX()
vramSetBankX()のXはA~Iです.
例:vramSetBankA(VRAM_A_MAIN_BG_0x06000000)
VRAM_AをMainの先頭に割り当てます.128KB以上使う予定ならさらにvramSetBankB(VRAM_B_MAIN_BG_0x06020000); 等としてセットします.
vramSetMainBanks()でA~Dの4つを一度に設定することも出来ます.
サンプル
テキストとビットマップを重ねて表示したい
consoleInitDefault()で簡単にフォントを用意して使えるのは,devkitproのサンプルを見ればすぐに分かると思います.ビットマップに重ねるにはどうすれば良いでしょうか.
まず,データのサイズからVRAM_Aをビットマップに,VRAM_Eあたりをテキストに割り当てる方針を立てます(メイン画面の場合).
フォントを格納するタイルデータのオフセットの都合で先頭の64Kに無いと駄目(?)なようなので,VRAM_Eを0x06000000に,VRAM_Aを0x06020000にマップする必要があります.
せっかくなので拡張回転BGを有効にしてMODE_3_2Dを使いましょう.
以上のことを考慮すると,こんな感じに初期化すればいいことになります.
videoSetMode(MODE_3_2D | DISPLAY_BG0_ACTIVE | DISPLAY_BG3_ACTIVE); vramSetBankE(VRAM_E_MAIN_BG); vramSetBankA(VRAM_A_MAIN_BG_0x06020000); BG0_CR = BG_MAP_BASE(0) | BG_TILE_BASE(1)| BG_PRIORITY(1); BG3_CR = BG_BMP16_256x256 | BG_BMP_BASE(2) | BG_PRIORITY(2); BG_PALETTE[0] = 0x0000; BG_PALETTE[255] = RGB15(31,31,31); consoleInitDefault((u16*)SCREEN_BASE_BLOCK(0), (u16*)CHAR_BASE_BLOCK(1), 16);