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

■モザイク Prev  Top  Next

今回は、モザイクです。最近どうもらくちんなポストエフェクトばっかりやってますが、決して手抜きではないので。

 
よくテレビや雑誌で見かけますな。大人の事情ってやつで見せたくない部分を隠すのによく使用します。でも最近はブラー使うほうが多いかな。 もちろんゲームでも使用します。RPGなどで戦闘シーンへの画面切り替えで徐々にモザイク具合を強くしたりします。ちょっと古いゲームですがPSPの「ブレイブストーリー 新たなる旅人」でやってました。 このゲームよかったな。HDRっぽいことやっててやわらかい光が表現されてたりしたんですよね。そのわりに軽快に動作してたし。PSPでもこのくらいできるんだって製作者側の意気込みが伝わるゲームでした。

実装方法は大まかに次のようになります。

1.レンダーターゲットサーフェイスにシーンをレンダリングする
2.1で取得したテクスチャーをサンプラーステートの縮小フィルタと拡大フィルタを両方「最近点フィルタ」を使用してスクリーン全体に2Dオブジェクトを使用してレンダリングする

となります。今回はシェーダーは使用しません。

ではソースを見ていきます。

---Main.cpp---


LPDIRECT3DDEVICE9 m_pd3dDevice = NULL;
D3DPRESENT_PARAMETERS m_d3dParameters;

//シーンのカラー情報を格納するサーフェイスの宣言
LPDIRECT3DTEXTURE9    m_pFullScreenTexture = NULL;
LPDIRECT3DSURFACE9    m_pFullScreenSurface = NULL;

UINT nWidth = 1024;
UINT nHeight = 768;

D3DXVECTOR4 LightDir = D3DXVECTOR4( 0.0f, -0.3f, 0.2f, 0.0f );

int APIENTRY WinMain( HINSTANCE hInstance,
                      HINSTANCE /*hPrevInstance*/,
                      LPSTR     /*lpCmpLine*/,
                      INT       /*nCmdShow*/)
{  
   HRESULT hr;
   
   D3DCAPS9 caps;
   
   //****************************************************************
   //ここでウィンドウクラスの登録処理を行う。
   //****************************************************************


   //****************************************************************
   //ここでウィンドウの作成処理
   //****************************************************************


   //****************************************************************
   //ここでDirect3Dの初期化を行う。
   //****************************************************************


   //****************************************************************
   //ここでオブジェクトのロード
   //****************************************************************

   //マテリアルの拡散反射色を設定する
   //テクスチャーを張らない場合を除き、すべてのオブジェクトで1.0fに設定してよいと思う。
   D3DMATERIAL9 Material;
   ZeroMemory( &Material, sizeof( Material ) );
   Material.Diffuse.r = 1.0f;
   Material.Diffuse.g = 1.0f;
   Material.Diffuse.b = 1.0f;
   Material.Diffuse.a = 1.0f;
   m_pd3dDevice->SetMaterial( &Material );

   //固定機能パイプラインライティングを設定する
   D3DLIGHT9 Light;

   ZeroMemory(&Light, sizeof(D3DLIGHT9));

   Light.Type = D3DLIGHT_DIRECTIONAL;
   Light.Direction = D3DXVECTOR3( 0.0f, -0.3f, 0.2f );
   Light.Ambient   = D3DXCOLOR( 1.0f, 1.0f, 1.0f, 0.0f );
   Light.Diffuse   = D3DXCOLOR( 1.0f, 1.0f, 1.0f, 0.0f );
   Light.Specular  = D3DXCOLOR( 0.0f, 0.0f, 0.0f, 0.0f );

   m_pd3dDevice->SetLight(0, &Light);
   m_pd3dDevice->LightEnable(0, TRUE);
   
   //****************************************************************
   //ここでメッセージループ処理を行う。
   //****************************************************************

}

//メッセージループからコールされる関数
BOOL MainLoop()
{
   //モザイク具合を制御する変数
   static float Scale = 1.0f;
   
   Scale+=0.01f;

   //シーンのレンダリング結果を格納するサーフェイス
   //レンダーターゲットサーフェイスのサイズを徐々に縮小する
   m_pd3dDevice->CreateTexture( (UINT)( nWidth / Scale ),
                                (UINT)( nHeight / Scale ),
                                1,
                                D3DUSAGE_RENDERTARGET,
                                D3DFMT_A8R8G8B8,
                                D3DPOOL_DEFAULT,
                                &m_pFullScreenTexture,
                                NULL );
   m_pFullScreenTexture->GetSurfaceLevel( 0, &m_pFullScreenSurface );

   //レンダーターゲットを切り替える         
   m_pd3dDevice->GetRenderTarget( 0, &OldSurface );
   m_pd3dDevice->SetRenderTarget( 0, m_pFullScreenSurface );
   
   //シーンのクリア
   m_pd3dDevice->Clear( 0L, 
                        NULL,
                        D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
                        0x0, 
                        1.0f,
                        0L );

   m_pd3dDevice->BeginScene();

   D3DXMATRIX matProj, matView, matWorld;

   //射影座標変換
   D3DXMatrixPerspectiveFovLH( &matProj,
                               D3DX_PI/4.0f,
                               4.0f / 3.0f,
                               11.0f,
                               220.0f );
   m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );

   //ビュー座標変換
   D3DXMatrixIdentity( &matView );   
   m_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );

   //ワールド座標変換
   D3DXMatrixIdentity( &matWorld );
   m_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );

   m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
   m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
   
   //****************************************************************
   //オブジェクトのレンダリング
   //****************************************************************

   //レンダーターゲットをバックバッファに戻す
   m_pd3dDevice->SetRenderTarget( 0, OldSurface );
   SafeRelease( OldSurface );
   
   //今回のポイント。
   //テクスチャーをメッシュに貼り付けるとき視点とオブジェクトの距離やオブジェクトのサイズにより
   //テクスチャーにスケーリングがかかる。D3DSAMP_MINFILTER はこのときのテクスチャーの品質を制御する。
   //D3DTEXF_POINT を指定するとぼかしがかからなくなる。
   
   //スクリーンサイズに対して、レンダーターゲットサーフェイスのサイズが小さくなるほど
   //レンダーターゲットサーフェイスが引き伸ばされ、1ピクセルの大きさが大きくなるのでモザイクの□も大きくなる。
   m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_POINT );
   m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT );

   m_pd3dDevice->SetTexture( 0, m_pFullScreenTexture );

   //****************************************************************
   //スクリーン全体に2Dオブジェクトでレンダリング
   //****************************************************************

   SafeRelease( m_pFullScreenSurface );
   SafeRelease( m_pFullScreenTexture );      
   
   m_pd3dDevice->EndScene();

   m_pd3dDevice->Present( NULL, NULL, NULL, NULL );

   return TRUE;
}

以上です。

今回はこれだけです。すみません。

Prev  Top  Next
inserted by FC2 system