NDS開発::グラフィック

DSのグラフィックの構成はかなり複雑で色々な設定に出来ます.様々なモードを駆使することで,比較的低スペックなDSでも高度な表現が可能です.設定に使うレジスタがとても多いので,ここで全ては説明できていません.

使えるリソース

主に,上記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(テキスト)

BGMainSub
0タイルタイル
1タイルタイル
2タイルタイル
3タイルタイル

Mode 1(テキスト+回転)

イメージを回転して表示できます.

BGMainSub
0タイルタイル
1タイルタイル
2タイルタイル
3回転回転

Mode 2(テキスト+回転x2)

BGMainSub
0タイルタイル
1タイルタイル
2回転回転
3回転回転

Mode 3(テキスト+拡張回転)

VRAM上のイメージを回転,スケーリング,オフセット指定して表示できます.このモードは便利.

BGMainSub
0タイルタイル
1タイルタイル
2タイルタイル
3拡張回転拡張回転

Mode 4(テキスト+回転+拡張回転)

BGMainSub
0タイルタイル
1タイルタイル
2回転回転
3拡張回転拡張回転

Mode 5(テキスト+拡張回転x2)

BGMainSub
0タイルタイル
1タイルタイル
2拡張回転拡張回転
3拡張回転拡張回転

Mode 6(大きなビットマップ)

MainのBG2で大きなビットマップを扱えるようです(?)

3Dモード

3Dモードでは,MainのBG0で3Dが使えるようになります.OpenGLに良く似たAPIが用意されているようです.

VRAMエリア(Bank)

VRAMとして使えるメモリのエリアは9個あります.単純に9枚のVRAMが確保できるわけではなくて,サイズや使える用途が異なります.

エリアサイズアドレス
VRAM_A128KB0x06800000
VRAM_B128KB0x06820000
VRAM_C128KB0x06840000
VRAM_D128KB0x06860000
VRAM_E64KB0x06880000
VRAM_F16KB0x06890000
VRAM_G16KB0x06894000
VRAM_H32KB0x06898000
VRAM_I16KB0x068A0000

というような構成です.

さらに,これらの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);
Copyright © 瓶詰堂 all rights reserved.