Platform SDK: DirectX

ステップ 2.2 : DirectDraw サーフェスをセットアップする

[Visual Basic]

ここでは、C および C++ でのアプリケーション開発について説明する。Visual Basic については、「Direct3D 直接モード Visual Basic チュートリアル」を参照すること。

[C++]

DirectDraw オブジェクトを作成し、その協調レベルを設定すると、アプリケーションがシーンのレンダリング、表示に使用するサーフェスが作成できる。サーフェスの作成方法は、アプリケーションがウィンドウ内またはフルスクリーン モードのどちらで実行されるかによって、ほぼ決定される。

フルスクリーン アプリケーションについて : フルスクリーン モードで実行するアプリケーションでは、上記のコードで示すようにしてサーフェスを作成できる。フルスクリーン アプリケーションでは、フルスクリーン排他モードに限って使用できる機能であるページ フリッピングを利用することが頻繁に行われている。この場合、2 つのサーフェスを明示的に作成するのではなく、単一の呼び出しで、サーフェスのフリッピング チェーンを作成することができる。詳細については、「複合サーフェスとフリッピング チェーンの作成」を参照すること。

サンプル Triangle は、ウィンドウ内で実行されるように設計されており、ディスプレイを表すプライマリ サーフェスの作成から始まる。

    DDSURFACEDESC2 ddsd;
    ZeroMemory( &ddsd, sizeof(DDSURFACEDESC2) );
    ddsd.dwSize         = sizeof(DDSURFACEDESC2);
    ddsd.dwFlags        = DDSD_CAPS;
    ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;

    // プライマリ サーフェスを作成する。
    hr = g_pDD->CreateSurface( &ddsd, &g_pddsPrimary, NULL );
    if( FAILED( hr ) )
        return hr;

プライマリ サーフェス記述には、寸法やピクセル フォーマットの情報は含まれない。このような特徴は、ディスプレイ モードと同じであると見なされているからである。現在のディスプレイ モードが、800×600 の 16 ビット カラーであれば、DirectDraw は、プライマリ サーフェスも同じであることを保証する。プライマリ サーフェスを作成すると、レンダリング ターゲットのサーフェスを作成することが可能になる。Triangle の場合、これは次のようにして作成される、別のオフスクリーン サーフェスとなる。

    ddsd.dwFlags        = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
    ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
 
    // バック バッファのサイズを設定する。
    // ウィンドウのサイズが変わる場合は、このサーフェスを破棄し、新しいサーフェスを作成する必要がある。
    GetClientRect( hWnd, &g_rcScreenRect );
    GetClientRect( hWnd, &g_rcViewportRect );
    ClientToScreen( hWnd, (POINT*)&g_rcScreenRect.left );
    ClientToScreen( hWnd, (POINT*)&g_rcScreenRect.right );
    ddsd.dwWidth  = g_rcScreenRect.right - g_rcScreenRect.left;
    ddsd.dwHeight = g_rcScreenRect.bottom - g_rcScreenRect.top;
 
    // バックバッファを作成する。
    // 最も可能性のあるエラー原因は、ビデオ メモリの不足である (洗練されたアプリケーションなら、このエラーに対処するべきである)。
    hr = g_pDD->CreateSurface( &ddsd, &g_pddsBackBuffer, NULL );
    if( FAILED( hr ) )
        return hr;

上記のコードは、プログラム ウィンドウのサイズと等しいオフスクリーン サーフェスを作成する。ユーザーへの表示範囲はウィンドウのサイズによって決まるため、このサイズより大きなサーフェスを作成する必要はない。(このコードでは、後でビューポートの設定およびアプリケーション ウィンドウのサイズと位置の追跡に使用する 2 つのグローバル変数も初期化する)。上記のコードが示すように、レンダリング ターゲットとして使用するサーフェスには、DDSCAPS_3DDEVICE 能力を指定する必要がある。この能力によって、システムは、3D レンダリングのみに使用される追加の内部データ構造体を割り当てる。プライマリ サーフェスを作成する場合と同様に、オフスクリーン サーフェスのピクセル フォーマットは、サーフェス記述で指定されていなければ、ディスプレイ モードと同じとされる。

 :  深度バッファを使用するアプリケーションでは、この時点で、1 つの深度バッファを作成して、レンダリング ターゲット サーフェスにアタッチする必要がある。このチュートリアルでは複雑になることを避けて深度バッファを使用していないが、「チュートリアル 2 : 深度バッファを追加する」および「深度バッファ」では使用する。

レンダリング ターゲットのプライマリ サーフェスを作成すると、DirectDrawClipper オブジェクトを作成して表示サーフェスにアタッチすることが可能になる。クリッパーを使用すると、ウィンドウが部分的にほかのウィンドウによって隠された場合や、ウィンドウが部分的に表示領域を越えた場合の処理をしなくて済む。クリッパーは、フルスクリーン モードで実行されるアプリケーションには必要ない。サンプル Triangle は、次のコードを使用してクリッパーを作成し、表示ウィンドウに結合している。

    LPDIRECTDRAWCLIPPER pcClipper;
    hr = g_pDD->CreateClipper( 0, &pcClipper, NULL );
    if( FAILED( hr ) )
        return hr;
 
    // ウィンドウ ハンドルにクリッパーを割り当てた後、
    // クリッパーを目的のサーフェスに設定する。
    pcClipper->SetHWnd( 0, hWnd );
    g_pddsPrimary->SetClipper( pcClipper );
    pcClipper->Release();

基本的な DirectDraw オブジェクトの作成を終了すると、シーンをレンダリングする Direct3D 主要オブジェクトの作成に進むことができる。サンプル Triangle では、このタスクを「ステップ 2.3 : Direct3D を初期化する」で行う。