高度な検索
Developer Connection
Member Login ログイン | ご入会 ADC連絡先

Technical Q&A QA1222
Using Clip Region and Buffer Rectangles with OpenGL Carbon


Q: AGL のバッファ矩形とクリップリージョンはどのように使用するのですか?

A: AGL バッファ矩形の使用方法とクリップリージョンの使用方法は、大変よく似ています。aglSetInteger を使用して矩形またはリージョンをセットアップし、次に、aglEnable または aglDisable を使用して、バッファ矩形とクリップリージョンの両者の機能を有効または無効にします。クライアントアプリケーションでは、矩形とリージョンのデータの有効化と設定は、コンテキストごとに実行する必要があります。なお、アプリケーションは通常の OpenGL クライアントコードですが、ここに示す手法は、ドロアブルと関連コンテキストを持つほかの Carbon OpenGL クライアントでも使用できます。

特定のコンテキストでバッファ矩形を使用するには、バッファ矩形を有効にするとともに、サイズも設定しなければなりません。リスト 1 に例を示します。


#include <AGL/agl.h>

// aglContext は、既存の有効なコンテキストでなければならない
short left = 10, bottom = 10, width = 300, height = 300;
GLint bufferRect[4];

bufferRect[0] = left; // 左辺は 0
bufferRect[1] = bottom; // 下辺は 0
bufferRect[2] = width; // バッファ矩形の幅
bufferRect[3] = height; // バッファ矩形の高さ
aglSetInteger (aglContext, AGL_BUFFER_RECT, bufferRect);
aglEnable (aglContext, AGL_BUFFER_RECT);

リスト 1. バッファ矩形のセットアップ


バッファ矩形がウインドウサイズに対応している場合、ウインドウサイズが変わるたびに、矩形を、通常は glViewport とともに再設定する必要があります。リセットは、kEventWindowShownkEventWindowBoundsChangedkEventWindowZoomed および kEventWindowResizeCompleted などの Carbon ウインドウイベントに応じて行うようにするとよいでしょう。さらに、ウインドウの内容が必ず最新の状態になるように、通常、kEventWindowActivatedkEventWindowDrawContent、および kEventWindowBoundsChanged などの Carbon ウインドウイベントが発生したら内容を描画するべきです。

AGL でのクリップリージョンの使用は、バッファ矩形の使用と大変よく似ています。具体的にいえば、クリップリージョンは、バッファ矩形とアップデート要件が同じです。クリップリージョンを設定するには、 OpenGL による更新を OpenGL が描画するべきウインドウ部分だけを含むリージョンに限定する QuickDraw リージョンを作成します。リスト 2 に示すコードはこの一例です。このコードでは、あるランダムな図形を用意し、4 つの既存のコントロールの境界矩形を除外して、クリップリージョンを作成しています。


#include <AGL/agl.h>
#include <Carbon/Carbon.h>


 static void SetClipRegion (WindowRef win)
{
    RgnHandle       clipRgn = NewRgn();
    RgnHandle       maskRgn = NewRgn();
    Rectangle       rectPort, bounds = { -32767, -32767, 32767, 32767 };
    ControlID       idControl;
    ControlRef      control;

    GetWindowPortBounds(win, &rectPort);
    // 何らかのランダムリージョンをセットアップする
    SetEmptyRgn (clipRgn);
    OpenRgn ();
    MoveTo (rectPort.left + 10, rectPort.top + 30);
    LineTo (rectPort.right - 20, rectPort.top + 50);
    LineTo (rectPort.right - 50, rectPort.bottom - 25);
    LineTo (rectPort.left + 10, rectPort.top + 50);
    CloseRgn (clipRgn);
    // 既存のコントロールの部分を切り抜く(ウインドウ内に 4 つあるものとする)
    idControl.signature = 'cbrt'; // アプリケーションは、nib で使用される
                                  // 任意のシグネチャを使用できる
    for (idControl.id = 0; idControl.id < 4; idControl.id++) {
        GetControlByID (win, &idControl, &control);
        GetControlBounds (control, &bounds);
        RectRgn(maskRgn, &bounds);
        DiffRgn(clipRgn, maskRgn, clipRgn);
    }
    // AGL 用にクリップリージョンを設定する
    // aglContext は、このウインドウ用にあらか
    // じめ用意されている有効なコンテキスト

    aglSetInteger (aglContext, AGL_CLIP_REGION, (const GLint *)clipRgn);
    DisposeRgn(clipRgn);
    DisposeRgn(maskRgn);
}

リスト 2. クリップリージョンのセットアップ


重要なのは、aglSetInteger を通じて AGL に渡すリージョンは手動で作成したものであり、ウインドウのクリップリージョンまたは可視リージョンには関連付けられない、と理解しておくことです。ウインドウのクリップリージョンを AGL に渡すことはできますが、クリップ領域に変更があるたびに、AGL のリージョンのコピーも手動で更新する必要があります。つまり、AGL Framework には、クリップリージョンを自動的に反映するネイティブな機能はないということです。このような仕様になったのは、QuickDraw 2D が描画しない箇所に OpenGL が描画する可能性が高く、描画の対象となる QuickDraw のクリップリージョンが、OpenGL の描画対象リージョンを除外した領域、またはそれに近いものになると考えられるからです。AGL のリージョンのコピーを、QuickDraw のクリップリージョンを除外した領域と同じに保ち続けるのは、どう見ても困難です。OpenGL が、アプリケーションの介在なしに非同期に更新される可能性もあるので、なおさらです。この AGL API は、クライアントアプリケーション用に設計されており、visRgnclipRgn といった既存のウインドウリージョンに対する特定の関係を一切持たないリージョンを直接提供します。

上述のように、AGL では、AGL_CLIP_REGION を指定した aglSetInteger の呼び出しの時点で、リージョンのコピーが作成されます。そのため、アプリケーションでは、aglSetinteger から処理が返ってきたあとは、いつでもリージョンを破棄できます。リージョンのコピー操作は、リージョンが複雑だと非常に負担が大きくなることがあるので、パフォーマンスが重視されるコードでは、AGL_CLIP_REGION を指定した aglSetinteger の使用は限定するべきです。

バッファ矩形を有効にするのと同じように、クリップリージョンも有効にする必要があることを忘れないでください。例をリスト 3 に示します。


#include <AGL/agl.h>

// aglContext は、既存の有効なコンテキスト
aglEnable (aglContext, AGL_CLIP_REGION);

リスト 3. クリップリージョンの有効化


リスト 3 のコードは、リスト 2 中の SetClipRegion コードに含めることもできます。この例ではコードを別々にしましたが、それは、クリップリージョンが有効になるたびにリージョン自体をリセットする必要がないからです。最後にもう一点、リージョンをウインドウサイズに対応するようにして作成した場合、サイズ変更に対する更新の要件はバッファ矩形の場合と同様です。

クリップリージョンとバッファ矩形はどちらも、ウインドウにおけるアクセラレートされたサーフェス描画のサイズと形状を限定する 2 通りの便利な方法を、AGL アプリケーションに提供します。これを利用して、AGL アプリケーションでは、アクセラレートされたサーフェスの対象になっていない範囲に 2D コンテンツを描画できます。バッファ矩形は Mac OS X の全てのバージョンで使用できますが、クリップリージョンは Mac OS X v10.2 以降においてのみ使用可能です。


[2002 年 12 月 3 日]