Microsoft Visual Studio .NET 2003
 Microsoft DirectX 9.0 SDK (December 2004)

■スクリーンショット作成 Prev  Top  Next
関連ページ:なし

2009/05/16: 画像フォーマットをBMPで正しく出力できないので修正
2009/05/16: IDirect3DDevice9インターフェースからIDirect3D9 インターフェイスを取得できるみたいなので関数の引数減らした

今回は、スクリーンショットを作成する関数を紹介します。作成したゲームをWebなどで紹介するときゲーム画面のイメージが必要となります。そのときキー入力一発で画像ファイルに出力できたら便利です。 「PrintScreen」キーを押して「Photo Shop」開いて、貼り付けて、ファイル保存してもできるけど面倒でしょう。

---ヘッダファイル宣言---


HRESULT CreateSnapshot( HWND HWnd, 
                        LPDIRECT3DDEVICE9 m_pd3dDevice, 
                        D3DPRESENT_PARAMETERS* m_d3dParameters,
                        D3DXIMAGE_FILEFORMAT FileFormat = D3DXIFF_JPG
                      );

---CreateSnapshot関数---


HRESULT CreateSnapshot( HWND HWnd, LPDIRECT3DDEVICE9 m_pd3dDevice, D3DPRESENT_PARAMETERS* m_d3dParameters, D3DXIMAGE_FILEFORMAT FileFormat )
{
   LPDIRECT3D9 pdirect3d9 = NULL;
   LPDIRECT3DSURFACE9 pSurface = NULL;
   D3DDISPLAYMODE dmode;
   int i;
   TCHAR fileName[100];
   FILE* f;

   i = 0;

   //出力する画像のフォーマットはbmpとjpgのみサポートします。
   //というよりjpg固定でいい気がしてきた。
   if( FileFormat != D3DXIFF_BMP && FileFormat != D3DXIFF_JPG )
   {
      return 1;
   }

   //imageフォルダを作成する。
   //なおパスは、実行ファイルからの相対パスにしている。
   //パスは自由に設定できるが、最初に規約を決めて作成するすべてのアプリケーション内で統一した方がいいと思う。
   CreateDirectory( _T("res\\image"), NULL );

   //ファイルを作成しすぎてディスクがパンクすることがないようにするため、とりあえずファイルの作成可能数は20に限定する。
   while( i < 20 )
   {
      //出力するフォーマットによってファイルの拡張子を変更する。
      switch( FileFormat )
      {
      case D3DXIFF_BMP:
         _stprintf( fileName, _T("res\\image\\image%02d.bmp"), i );
         break;
      case D3DXIFF_JPG:
         _stprintf( fileName, _T("res\\image\\image%02d.jpg"), i );
         break;
      }
      
      //ファイルがあるか
      f = _tfopen( fileName, _T("r") );
      
      //ファイルが見つからないときはループを抜ける
      if( f == NULL )
         break;

      fclose( f );

      i++;
   }   
   //スクリーンショットの作成可能数をオーバーしているため作成できません。
   if( i == 20 )
   {
      return 2;
   }

   //IDirect3D9 インターフェイス を取得する
   m_pd3dDevice->GetDirect3D( &pdirect3d9 );

   //現在のディスプレイフォーマットを取得
   if( FAILED( pdirect3d9->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &dmode ) ) )
   {
      SafeRelease( pdirect3d9 );
      return -1;
   }
   //これしないとメモリリークする
   SafeRelease( pdirect3d9 );

   //キャプチャ用のサーフェイスを作成
   if( FAILED( m_pd3dDevice->CreateOffscreenPlainSurface( dmode.Width,
                                                          dmode.Height, 
                                                          D3DFMT_A8R8G8B8,
                                                          D3DPOOL_SCRATCH,
                                                          &pSurface,
                                                          NULL ) ) )
   {
      return -2;
   }
   
   //サーフェイスにフロントバッファのイメージを保存する
   if( FAILED( m_pd3dDevice->GetFrontBufferData( 0, pSurface ) ) )
   {
      SafeRelease( pSurface );
      return -3;
   }

   //ウィンドウモードのとき
   if( m_d3dParameters->Windowed == TRUE )
   {
      RECT wrc;      
      
      //ウィンドウの座標を取得
      GetWindowRect( HWnd, &wrc );

      //ファイル出力
      if( FAILED(  D3DXSaveSurfaceToFile( fileName, FileFormat, pSurface, NULL, &wrc ) ) )
      {
         SafeRelease( pSurface );
         return -4;
      }

   }
   
   //フルスクリーンのとき
   else
   {
      //ファイル出力
      if( FAILED(  D3DXSaveSurfaceToFile( fileName, FileFormat, pSurface, NULL, NULL ) ) )
      {
         SafeRelease( pSurface );
         return -5;
      }
   }

   SafeRelease( pSurface );

   return 0;
}

以上です。しょーもないネタでしたが、シェーダーよかこういうネタの方が重要だと思います(いいわけ)。

Prev  Top  Next
inserted by FC2 system