マルチレイヤ/マルチディスプレイ
マルチレイヤ、マルチディスプレイは同じように動作します。各レイヤ/ディスプレイはそれぞれ色、サイズなどもちます。また非常に簡単にマルチレイヤを初期化できます。レイヤの最大数はGUIConf.hにあるGUI_NUM_LAYERSで定義され、各レイヤーは初期化中に対応するディスプレイドライバを割り当てられなければなりません。レイヤの最大数の設定上限はありません。任意のレイヤーまたはディスプレイに対して自由にウィンドウを設置でき、描画操作も行えます。マルチレイヤとマルチディスプレイの間の違いは極僅かではとんどありません。同じAPIを使用することができます。なので以下ではマルチディスプレイをマルチレイヤと特に区別せずマルチレイヤとのみ呼びます。
描画レイヤーの選択
描画操作する場合、デフォルトではレイヤー0を使用します。GUI_SelLayer() で他のレイヤーを選択することができます。
サンプルコード
void MainTask(void) { GUI_Init(); /* Draw something on default layer 0 */ GUI_SetBkColor(GUI_GREEN); GUI_Clear(); GUI_DispStringHCenterAt("Layer 0", 100, 46); /* Draw something on layer 1 */ GUI_SelLayer(1); /* Select layer 1 */ GUI_SetBkColor(GUI_RED); GUI_Clear(); GUI_SetColor(GUI_BLUE); GUI_FillRect(20, 20, 179, 79); GUI_SetColor(GUI_WHITE); GUI_SetTextMode(GUI_TM_TRANS); GUI_DispStringHCenterAt("Layer 1", 100, 46); while(1) { GUI_Delay(100); } }
上記のサンプルのスクリーンショット
ウィンドウのレイヤー選択
ウィンドウマネージャは、自動的にウィンドウがどのレイヤーに配置されているかを追跡します。ウィンドウマネージャを使用すると、すべてのレイヤは、最上位レベル(デスクトップ)のウィンドウを持っています。レイヤにあるデスクトップウィンドウの下位ウィンドウのみ表示されることになります。どのデスクトップウィンドウを上位に持つかでウィンドウの所属するレイヤを追跡しています。
サンプルコード
次のサンプルは、2つのデスクトップウィンドウ上で、3つのウィンドウを作成します。
hWin0 = WM_CreateWindowAsChild( 10, 20, 80, 70, WM_GetDesktopWindowEx(0), WM_CF_SHOW, _cbWin0, 0); /* Create 2 child windows on destop 1 */ hWin1 = WM_CreateWindowAsChild( 10, 20, 80, 70, WM_GetDesktopWindowEx(1), WM_CF_SHOW, _cbWin1, 0); hWin2 = WM_CreateWindowAsChild(110, 20, 80, 70, WM_GetDesktopWindowEx(1), WM_CF_SHOW, _cbWin2, 0);
上記のサンプルのスクリーンショット
スクリーンショット
ウィンドウの階層
ウィンドウのレイヤ間移動
任意の時にウィンドウのレイヤ簡易動作黄砂を行えます。これは移動したいウィンドウの上位デスクトップウィンドウを変更すればいいだけです。これだけでウィンドウを移動させることができます。
サンプルコード
次のサンプルでは、親ウィンドウからウィンドウを切り離す方法と新しい親ウィンドウに付加する例です。
/* Create 1 child window on destop 0 */ hWin0 = WM_CreateWindowAsChild( 10, 20, 80, 70, WM_GetDesktopWindowEx(0), WM_CF_SHOW, _cbWin0, 0); /* Create 2 child windows on destop 1 */ hWin1 = WM_CreateWindowAsChild( 10, 20, 80, 70, WM_GetDesktopWindowEx(1), WM_CF_SHOW, _cbWin1, 0); hWin2 = WM_CreateWindowAsChild(110, 20, 80, 70, WM_GetDesktopWindowEx(1), WM_CF_SHOW, _cbWin2, 0); GUI_Delay(1000); /* Detach window 2 from desktop 1 and attach it to desktop 0 */ WM_AttachWindow(hWin2, WM_GetDesktopWindowEx(0));
スクリーンショット
ウィンドウの階層
親ウィンドウからウィンドウを切り離し新しい親ウィンドウに付加します。
スクリーンショット
ウィンドウの階層
マルチレイヤの使用
emWinはマルチレイヤーを区別しません。マルチレイヤーを使用する場合は、通常各レイヤーのサイズとドライバは同じです。ビューアでは各レイヤーを別のウィンドウで表示します。ビューアの合成結果ウィンドウには、全てのレイヤを階層の高い順に重ねた結果が表示されます。
透明度
通常階層の高いレイヤによって階層の低いレイヤの画像は隠されてしまいます。これを階層の高いレイヤのカラーインデックスが0の部分は透明とみなして下の階層の画像が表示されます。これを透明度と呼びます
サンプル
次の例では、透過性の使い方を紹介しています。レイヤー0に3本のカラーバーを描画し、レイヤ1が白で塗りつぶされ、3つの透明なアイテムが描かれています。
GUI_SelectLayer(0);
GUI_SetColor(GUI_RED);
GUI_FillRect(0、0、199、33);
GUI_SetColor(GUI_GREEN);
GUI_FillRect(0、34、199、66);
GUI_SetColor(GUI_BLUE);
GUI_FillRect(0、67、199、1"、100、4); GUI_SetColor(GUI_TRANSPARENT); GUI_FillCircle(100、50、35); GUI_FillRect(10、10、40、90); GUI_FillRect(160、10、190、90);
サンプルののスクリーンショット
レイヤ0
レイヤ1
レイヤ2(合成結果)
アルファブレンディング
アルファブレンディングは、透過をつかった画像の合成手法です。たとえばあるピクセルについてレイヤー0とレイヤー1の色ををれぞれC0とC1とすると、表示される色Crは次のように計算します。(Aはアルファ値で自由に設定できます)
Cr = C0 *(1 - A)+ C1 *
内部的には色情報は32ビット値として処理しています。下位24ビットは色情報、上位8ビットはアルファブレンディングの透過度として管理されます。0x00のアルファ値は不透明と0xFFは、(見えない)完全に透明を意味します。
アルファブレンディングは3つの方法でできます。
- レイヤーのアルファブレンディング:レイヤーでアルファブレンディングを管理(LCD_SetAlphaEx()で設定)
- ルックアップテーブル(LUT)アルファブレンディングをルックアップ:LUTを使用してアルファブレンディングを管理
- ピクセルアルファブレンディング:ピクセルごとにアルファブレンディングを管理
サンプル
次の例では、ピクセルのアルファブレンディングを紹介します。レイヤー0に円を描画し、垂直方向にグラデーションをかけたアルファ値で黄色の三角形を描きます。
GUI_SetColor(GUI_BLUE);
GUI_FillCircle(100, 50, 49);
GUI_SetBkColor(GUI_TRANSPARENT);
GUI_Clear();
for (i = 0; i < 100; i++) {
U32 Alpha;
Alpha = (i * 255 / 100) << 24;
GUI_SetColor(GUI_YELLOW | Alpha);
GUI_DrawHLine(i, 100 - i, 100 + i);
}
サンプルのスクリーンショット
レイヤ0
レイヤ1
レイヤ2(合成結果)