基本

1 〜 3 は、固定機能パイプライン、4 〜 6 は、メッシュ、7 と 8 は、DirectX9.0 のシェーダ。  最近は、ノートパソコンでもプログラマブル シェーダにハード的に対応するようになったから、旧式の固定機能パイプラインは、Direct3D10 以降では使えなくなった。 4 〜 6 も固定機能だが、メッシュはシェーダでも使う。

サンプル コードのダウンロード
  1. 頂点色を指定して描画
  2. テクスチャーを貼る
  3. ライト有効化
  4. ティーポットの描画
  5. メッシュ
  6. 宣言子
  7. 頂点シェーダ
  8. ピクセル シェーダ





 頂点色を指定して描画

 三角形のポリゴンの各頂点に、赤、緑、青の各色を設定して描画する。
#include <d3dx9.h>

#pragma comment(lib,"d3d9.lib")
#pragma comment(lib,"d3dx9.lib")

#define MYWNDTITLE      "DX9_Basis1"
#define MYWNDCLASS      "CLASS_DX9_Basis1"
#define WIDTH           320             // 画面の横のサイズ
#define HEIGHT          240             // 画面の縦のサイズ

struct LVERTEX          // 頂点フォーマット構造体
{
    D3DXVECTOR3 v;      // 頂点座標
    D3DCOLOR    c;      // 頂点色
};
#define FVF_LVERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE)    // 頂点フォーマットの定義

// メッシュの各頂点のデータ形式を定義する。
// D3DXVECTOR3 v; が D3DFVF_XYZ に、D3DCOLOR c; が D3DFVF_DIFFUSE に対応する。
// D3DFVF_XYZ と D3DFVF_DIFFUSE の順番は逆にしても良いが、v と c は順番が決まっている。
// 頂点フォーマット構造体の順番は、頂点座標(float ×3)、RHW(float)、
// 頂点の重み(float ×1〜3)、頂点法線(float ×3)、頂点のポイントサイズ(float)、
// ディフューズ色(DWORD)、スペキュラ色(DWORD)、テクスチャ座標1〜8(float ×1〜4)
// となっており、使いたいものだけ選択する。
// ここでは、頂点座標とディフューズ色だけ使用した。

LPDIRECT3D9             g_pD3D = NULL;
LPDIRECT3DDEVICE9       g_pD3DDev = NULL;
D3DPRESENT_PARAMETERS   g_d3dpp;

// 初期設定
HRESULT Initialize(HWND hWnd)
{
    // Direct3D9 を作成
    g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
    
    ZeroMemory( &g_d3dpp, sizeof(g_d3dpp) );
    g_d3dpp.Windowed = TRUE;                    // TRUE:ウィンドウモード, FALSE:フルスクリーンモード
    g_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; // D3DSWAPEFFECT_DISCARD が最も高速に描画されるらしい
    g_d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;  // バックバッファのフォーマット
    g_d3dpp.EnableAutoDepthStencil = TRUE;
    g_d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
//  g_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
    // EnableAutoDepthStencil は、Z 座標を使用する場合には必ず、TRUE にする。
    // AutoDepthStencilFormat に D3DFMT_D16 を設定すると、
    // バックバッファの各ピクセル(画素)に Z 座標用の 16 bit のメモリ領域が確保される。
    // つまり、WIDTH * HEIGHT * 16 ビットのメモリ領域が確保される。
    // PresentationInterval に D3DPRESENT_INTERVAL_IMMEDIATE を設定すると、
    // ディスプレイのリフレッシュレートに同期せずに描画されるようになる。
    // 実際の描画は、リフレッシュレート(1秒間に60回描画)以上の速度にはならないのだが、
    // Direct3D のサンプルでは、これを採用しているから、内部的には数百 FPS 以上出ている。
    
    // D3D9Device を作成
    g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
                                      D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                      &g_d3dpp, &g_pD3DDev );
    
    // カリング設定
    g_pD3DDev->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
    // カリングは、ポリゴンの片面と両面のどちらを描画するかを設定する。
    // 通常、描画のオーバーヘッドを減らすために、片面のみを描画する。
    // D3DCULL_NONE            : 両面を描画する。
    // D3DCULL_CW, D3DCULL_CCW : 頂点の並びが右回りか左回りの面のみを描画する。
    // 何も描画されない場合、一度、両面を描画してみる。
    // 裏面が表示されていると思った場合は、逆面に設定する。
    
    // Zバッファ有効化(描画に Z 座標が適用される)
    g_pD3DDev->SetRenderState(D3DRS_ZENABLE, TRUE);
    
    // ライト無効化
    g_pD3DDev->LightEnable(0, false);
    g_pD3DDev->SetRenderState(D3DRS_LIGHTING, false);
    // 頂点フォーマットの定義に法線ベクトルを入れない場合は、ライトは無効にしなくてはならない。
    // その場合は、必ず、頂点フォーマットの定義に頂点色を入れなくてはならない。
    
    // 頂点フォーマット設定
    g_pD3DDev->SetFVF(FVF_LVERTEX);
    
    D3DXMATRIX matView;
    // ビュー行列を作成する
    D3DXMatrixLookAtLH(&matView,&D3DXVECTOR3(0,0,-2.5f),&D3DXVECTOR3(0,0,0),&D3DXVECTOR3(0,1,0));
    // 最初の引数は受け取る行列、2つ目は視点の座標、
    // 3つ目は注視点の座標、4つ目はモデルの上方向のベクトル
    
    // ビュー行列設定
    g_pD3DDev->SetTransform(D3DTS_VIEW,&matView);
    
    D3DXMATRIX matProj;
    // プロジェクション行列を作成する
    D3DXMatrixPerspectiveFovLH(&matProj,D3DX_PI/4,(float)WIDTH/HEIGHT,0.01f,10.0f);
    // 最初の引数は受け取る行列、2つ目は視野で通常は45度、3つ目は縦横比、
    // 4つ目は視点に最も近い Z 座標、5つ目は視点から最も遠い Z 座標
    
    // プロジェクション行列設定
    g_pD3DDev->SetTransform(D3DTS_PROJECTION,&matProj);
    
    return S_OK;
}// Initialize

// 終了処理
void Cleanup()
{
    // Direct3D オブジェクトを解放
    if(g_pD3DDev){
        g_pD3DDev->Release();
        g_pD3DDev = NULL;
    }
    if(g_pD3D){
        g_pD3D->Release();
        g_pD3D = NULL;
    }
}// Cleanup

// 描画
void Draw()
{
    LVERTEX lv[3]; // 三角形は頂点が3つ
    
    // バックバッファを第3引数の色(この場合は黒)で塗りつぶし、Z 座標を総て 0 に設定する
    g_pD3DDev->Clear(0,NULL,D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(0,0,0),1.0f,0);
    
    // 描画開始
    g_pD3DDev->BeginScene();
    
    lv[0].v.x = -0.5f;                    // X 座標
    lv[0].v.y = 0.5f;                     // Y 座標
    lv[0].v.z = 0;                        // Z 座標
    lv[0].c = D3DCOLOR_ARGB(255,255,0,0); // 色(透明度、赤、緑、青)、この場合は、不透明の赤色
    lv[1].v.x = 0.5f;
    lv[1].v.y = 0.5f;
    lv[1].v.z = 0;
    lv[1].c = D3DCOLOR_ARGB(255,0,255,0);
    lv[2].v.x = 0;
    lv[2].v.y = -0.5f;
    lv[2].v.z = 0;
    lv[2].c = D3DCOLOR_ARGB(255,0,0,255);
    
    // ポリゴンの描画
    g_pD3DDev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN,1,lv,sizeof(LVERTEX));
    // 第2引数は、プリミティブの数である。
    // プリミティブとは、三角形のポリゴンの事であり、多角形は三角形ポリゴンを組み合わせて作成する。
    // 例えば、四角形の場合は、三角形を2つ組み合わせるので、プリミティブ数は、2 となる。
    // 第1引数の D3DPT_TRIANGLEFAN は組み合わせ方である。
    
    // 描画終了
    g_pD3DDev->EndScene();
    
    // バックバッファとフロントバッファを交換する
    g_pD3DDev->Present(NULL,NULL,NULL,NULL);
}// Draw

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    {
    case WM_CREATE:
        Initialize(hWnd);           // 初期設定
        break;
        
    case WM_PAINT:
        Draw();                     // オブジェクトの描画
        break;
        
    case WM_KEYDOWN:
        switch ( wParam )
        {
        case VK_ESCAPE:             // [ESC] キーが押されると終了
            SendMessage(hWnd, WM_CLOSE, 0, 0);
            break;
        }
        break;
        
    case WM_CLOSE:
        DestroyWindow(hWnd);
        Cleanup();                  // 終了処理
        PostQuitMessage(0);
        break;

    default:
        return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }
    return 0;
}// WndProc

int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR lpCmdLine,int nCmdShow)
{
    WNDCLASSEX  wc;
    HWND        hWnd;

    ZeroMemory(&wc, sizeof(wc));
    wc.cbSize           = sizeof(WNDCLASSEX); 
    wc.lpfnWndProc      = (WNDPROC)WndProc;
    wc.hInstance        = hInst;
    wc.hIcon            = LoadIcon(hInst,IDI_WINLOGO);
    wc.hCursor          = LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW));
    wc.hbrBackground    = (HBRUSH)GetStockObject(BLACK_BRUSH);
    wc.lpszClassName    = MYWNDCLASS;
    if(RegisterClassEx(&wc) == 0)
        return 0;

    hWnd = CreateWindowEx(0, 
                MYWNDCLASS,
                MYWNDTITLE,
                WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX | WS_VISIBLE,
                CW_USEDEFAULT, CW_USEDEFAULT, WIDTH, HEIGHT,
                NULL,
                NULL,
                hInst,
                NULL);
    
    MSG msg; 
    while(GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}// WinMain

	
トップへ 前へ 次へ

 テクスチャーを貼る

 長方形メッシュの各頂点に、赤、黄、緑、青の各色を設定し、テクスチャーを貼り付けて描画する。
#include <d3dx9.h>

#pragma comment(lib,"d3d9.lib")
#pragma comment(lib,"d3dx9.lib")

#define MYWNDTITLE      "DX9_Basis2"
#define MYWNDCLASS      "CLASS_DX9_Basis2"
#define WIDTH           320
#define HEIGHT          240

struct LVERTEX
{
    D3DXVECTOR3 v;      // 頂点座標
    D3DCOLOR    c;      // 頂点色
    float       tu,tv;  // テクスチャー座標
};
#define FVF_LVERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1)

// D3DXVECTOR3 v; が D3DFVF_XYZ に、D3DCOLOR c; が D3DFVF_DIFFUSE に、
// float tu,tv; が D3DFVF_TEX1 に対応する。

LPDIRECT3D9             g_pD3D = NULL;
LPDIRECT3DDEVICE9       g_pD3DDev = NULL;
D3DPRESENT_PARAMETERS   g_d3dpp;
LPDIRECT3DTEXTURE9      g_pTex = NULL;      // テクスチャー

// 初期設定
HRESULT Initialize(HWND hWnd)
{
    ここまでは、上のサンプルに同じ
    
    // カレント ディレクトリーを実行ファイルのディレクトリーに設定
    char path[MAX_PATH];
    GetModuleFileName(NULL,path,sizeof(path));
    char *p = strrchr(path, '\\');
    if(p){
        strcpy(p, "");
        SetCurrentDirectory(path);
    }
    // テクスチャーの読み込み
    D3DXCreateTextureFromFile(g_pD3DDev, "tex1.png", &g_pTex);
    
    return S_OK;
}// Initialize

// 終了処理
void Cleanup()
{
    // テクスチャーを解放
    if(g_pTex){
        g_pTex->Release();
        g_pTex = NULL;
    }
    // Direct3D オブジェクトを解放
    if(g_pD3DDev){
        g_pD3DDev->Release();
        g_pD3DDev = NULL;
    }
    if(g_pD3D){
        g_pD3D->Release();
        g_pD3D = NULL;
    }
}// Cleanup

// 描画
void Draw()
{
    LVERTEX lv[4];	// 長方形は頂点が4つ
    
    g_pD3DDev->Clear(0,NULL,D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(0,0,0),1.0f,0);
    g_pD3DDev->BeginScene();
    lv[0].v.x = -0.5f;                    // X 座標
    lv[0].v.y = 0.5f;                     // Y 座標
    lv[0].v.z = 0;                        // Z 座標
    lv[0].c = D3DCOLOR_ARGB(255,255,0,0); // 色(赤)
    lv[0].tu = 0;                         // テクスチャーの X 座標(比率で表す。1.0が100%)
    lv[0].tv = 0;                         // テクスチャーの Y 座標(比率で表す。1.0が100%)
    lv[1].v.x = 0.5f;
    lv[1].v.y = 0.5f;
    lv[1].v.z = 0;
    lv[1].c = D3DCOLOR_ARGB(255,255,255,0);
    lv[1].tu = 1;
    lv[1].tv = 0;
    lv[2].v.x = 0.5f;
    lv[2].v.y = -0.5f;
    lv[2].v.z = 0;
    lv[2].c = D3DCOLOR_ARGB(255,0,255,0);
    lv[2].tu = 1;
    lv[2].tv = 1;
    lv[3].v.x = -0.5f;
    lv[3].v.y = -0.5f;
    lv[3].v.z = 0;
    lv[3].c = D3DCOLOR_ARGB(255,0,0,255);
    lv[3].tu = 0;
    lv[3].tv = 1;
    if(g_pTex)
        g_pD3DDev->SetTexture(0, g_pTex);   // テクスチャーを適用
    g_pD3DDev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN,2,lv,sizeof(LVERTEX)); // 四角形なのでプリミティブ数は 2 つ
    g_pD3DDev->EndScene();
    g_pD3DDev->SetTexture(0, NULL);         // テクスチャーの解除(描画後は解除する)
    g_pD3DDev->Present(NULL,NULL,NULL,NULL);
}// Draw

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    上のサンプルに同じ
}// WndProc

int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR lpCmdLine,int nCmdShow)
{
    上のサンプルに同じ
}// WinMain
	
トップへ 前へ 次へ

 ライト有効化

 上のサンプルに更に法線ベクトルを追加し、ライトを有効化する
 ライトを使う場合は、頂点法線ベクトルが必要である。
#include <d3dx9.h>

#pragma comment(lib,"d3d9.lib")
#pragma comment(lib,"d3dx9.lib")

#define MYWNDTITLE      "DX9_Basis3"
#define MYWNDCLASS      "CLASS_DX9_Basis3"
#define WIDTH           320
#define HEIGHT          240

struct LVERTEX
{
    D3DXVECTOR3 v;      // 頂点座標
    D3DXVECTOR3 n;      // 法線ベクトル
    D3DCOLOR    c;      // 頂点色
    float       tu,tv;  // テクスチャー座標
};
#define FVF_LVERTEX (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX1)

// D3DXVECTOR3 v; が D3DFVF_XYZ に、D3DXVECTOR3 n; が D3DFVF_NORMAL に、
// D3DCOLOR c; が D3DFVF_DIFFUSE に、float tu,tv; が D3DFVF_TEX1 に対応する。

LPDIRECT3D9             g_pD3D = NULL;
LPDIRECT3DDEVICE9       g_pD3DDev = NULL;
D3DPRESENT_PARAMETERS   g_d3dpp;
LPDIRECT3DTEXTURE9      g_pTex = NULL;      // テクスチャー

// 照明設定
void Set_Light()
{
    D3DXVECTOR3 vecDir;
    D3DLIGHT9   light;
    
    ZeroMemory( &light, sizeof(D3DLIGHT9) );
    light.Type      = D3DLIGHT_DIRECTIONAL; // ライトの種類(ここでは、平行光線)
    light.Diffuse.r = 1.0f;                 // ライトの色
    light.Diffuse.g = 1.0f;
    light.Diffuse.b = 1.0f;
    vecDir = D3DXVECTOR3(0.866025f,-0.5f,0.5f); // ライトの方向を示すベクトル
    // ベクトルの正規化
    D3DXVec3Normalize((D3DXVECTOR3*)&light.Direction, &vecDir);
    
    g_pD3DDev->SetLight(0, &light);
    g_pD3DDev->LightEnable(0, TRUE);
    g_pD3DDev->SetRenderState(D3DRS_AMBIENT, 0x00909090); // 画面全体の明るさ
}// Set_Light

// マテリアル設定(メッシュの質感設定)
void Set_Material()
{
    D3DMATERIAL9    mtrl;
    
    ZeroMemory(&mtrl, sizeof(D3DMATERIAL9));
    mtrl.Diffuse.a = 1.0f; // メッシュの色
    mtrl.Diffuse.r = 1.0;
    mtrl.Diffuse.g = 1.0;
    mtrl.Diffuse.b = 1.0;
    mtrl.Ambient = mtrl.Diffuse; // メッシュ全体の明るさも色と同じ
    g_pD3DDev->SetMaterial(&mtrl);
}// Set_Material

// 初期設定
HRESULT Initialize(HWND hWnd)
{
    ここまでは上のサンプルに同じ
    
    // 頂点データにに法線ベクトルを加える場合は、
    // 照明とマテリアルの両方を設定しなくてはならない
    
    // 照明設定
    Set_Light();
    // マテリアル設定
    Set_Material();
    
    return S_OK;
}// Initialize

// 終了処理
void Cleanup()
{
    上のサンプルに同じ
}// Cleanup

// 描画
void Draw()
{
    LVERTEX lv[4];
    
    g_pD3DDev->Clear(0,NULL,D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(0,0,0),1.0f,0);
    g_pD3DDev->BeginScene();
    lv[0].v.x = -0.5f;                    // X 座標
    lv[0].v.y = 0.5f;                     // Y 座標
    lv[0].v.z = 0;                        // Z 座標
    lv[0].n.x = 0;                        // 法線ベクトルの X 成分
    lv[0].n.y = 0;                        // 法線ベクトルの Y 成分
    lv[0].n.z = -1.0f;                    // 法線ベクトルの Z 成分
    lv[0].c = D3DCOLOR_ARGB(255,255,0,0); // 色(赤)
    lv[0].tu = 0;                         // テクスチャーの X 座標
    lv[0].tv = 0;                         // テクスチャーの Y 座標
    lv[1].v.x = 0.5f;
    lv[1].v.y = 0.5f;
    lv[1].v.z = 0;
    lv[1].n.x = 0;
    lv[1].n.y = 0;
    lv[1].n.z = -1.0f;
    lv[1].c = D3DCOLOR_ARGB(255,255,255,0);
    lv[1].tu = 1;
    lv[1].tv = 0;
    lv[2].v.x = 0.5f;
    lv[2].v.y = -0.5f;
    lv[2].v.z = 0;
    lv[2].n.x = 0;
    lv[2].n.y = 0;
    lv[2].n.z = -1.0f;
    lv[2].c = D3DCOLOR_ARGB(255,0,255,0);
    lv[2].tu = 1;
    lv[2].tv = 1;
    lv[3].v.x = -0.5f;
    lv[3].v.y = -0.5f;
    lv[3].v.z = 0;
    lv[3].n.x = 0;
    lv[3].n.y = 0;
    lv[3].n.z = -1.0f;
    lv[3].c = D3DCOLOR_ARGB(255,0,0,255);
    lv[3].tu = 0;
    lv[3].tv = 1;
    if(g_pTex)
        g_pD3DDev->SetTexture(0, g_pTex);   // テクスチャーを適用
    g_pD3DDev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN,2,lv,sizeof(LVERTEX));
    g_pD3DDev->EndScene();
    g_pD3DDev->SetTexture(0, NULL);         // テクスチャーの解除
    g_pD3DDev->Present(NULL,NULL,NULL,NULL);
}// Draw

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    上のサンプルに同じ
}// WndProc

int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR lpCmdLine,int nCmdShow)
{
    上のサンプルに同じ
}// WinMain
	
トップへ 前へ 次へ

 ティーポットの描画

 
#include <d3dx9.h>

#pragma comment(lib,"d3d9.lib")
#pragma comment(lib,"d3dx9.lib")

#define MYWNDTITLE      "DX9_Basis4"
#define MYWNDCLASS      "CLASS_DX9_Basis4"
#define WIDTH           320
#define HEIGHT          240

LPDIRECT3D9             g_pD3D = NULL;
LPDIRECT3DDEVICE9       g_pD3DDev = NULL;
D3DPRESENT_PARAMETERS   g_d3dpp;
LPD3DXMESH              g_pMeshTea = NULL;  // Xメッシュ

// 照明設定
void Set_Light()
{
    D3DXVECTOR3 vecDir;
    D3DLIGHT9   light;
    
    ZeroMemory( &light, sizeof(D3DLIGHT9) );
    light.Type      = D3DLIGHT_DIRECTIONAL;
    light.Diffuse.r = 1.0f;
    light.Diffuse.g = 1.0f;
    light.Diffuse.b = 1.0f;
    light.Specular = light.Diffuse; // 今回はスペキュラ−色(金属的な反射)を設定
    vecDir = D3DXVECTOR3(0.866025f,-0.5f,0.5f);
    D3DXVec3Normalize((D3DXVECTOR3*)&light.Direction, &vecDir);
    
    g_pD3DDev->SetLight(0, &light);
    g_pD3DDev->LightEnable(0, TRUE);
    g_pD3DDev->SetRenderState(D3DRS_AMBIENT, 0x00909090);
    // スペキュラ−色を有効化
    g_pD3DDev->SetRenderState(D3DRS_SPECULARENABLE, TRUE);
    g_pD3DDev->SetRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
}// Set_Light

// マテリアル設定
void Set_Material()
{
    D3DMATERIAL9    mtrl;
    
    ZeroMemory(&mtrl, sizeof(D3DMATERIAL9));
    mtrl.Diffuse.a = 1.0f;
    mtrl.Diffuse.r = 0.0;
    mtrl.Diffuse.g = 0.0;
    mtrl.Diffuse.b = 1.0;
    mtrl.Ambient = mtrl.Diffuse;
    mtrl.Specular.a = 1.0f; // マテリアルにもスペキュラ−色を設定
    mtrl.Specular.r = 1.0f;
    mtrl.Specular.g = 1.0f;
    mtrl.Specular.b = 1.0f;
    mtrl.Power = 50;        // スペキュラ−色の強度
    g_pD3DDev->SetMaterial(&mtrl);
}// Set_Material

// 初期設定
HRESULT Initialize(HWND hWnd)
{
    // Direct3D9 を作成
    g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
    
    ZeroMemory( &g_d3dpp, sizeof(g_d3dpp) );
    g_d3dpp.Windowed = TRUE;
    g_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    g_d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
    g_d3dpp.EnableAutoDepthStencil = TRUE;
    g_d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
//  g_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
    
    // D3D9Device を作成
    g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
                                      D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                      &g_d3dpp, &g_pD3DDev );
    
    // カリング設定
    g_pD3DDev->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
    // Zバッファ有効化
    g_pD3DDev->SetRenderState(D3DRS_ZENABLE, TRUE);
    
    // Xファイル オブジェクトは頂点フォーマット設定が不要
    
    // ビュー行列設定
    D3DXMATRIX matView;
    D3DXMatrixLookAtLH(&matView,&D3DXVECTOR3(0,0,-5.0f),&D3DXVECTOR3(0,0,0),&D3DXVECTOR3(0,1,0));
    g_pD3DDev->SetTransform(D3DTS_VIEW,&matView);
    // プロジェクション行列設定
    D3DXMATRIX matProj;
    D3DXMatrixPerspectiveFovLH(&matProj,D3DX_PI/4,(float)WIDTH/HEIGHT,0.01f,10.0f);
    g_pD3DDev->SetTransform(D3DTS_PROJECTION,&matProj);
    
    // 照明設定
    Set_Light();
    // マテリアル設定
    Set_Material();
    // ティーポットの作成
    D3DXCreateTeapot(g_pD3DDev, &g_pMeshTea, NULL);
    
    return S_OK;
}// Initialize

// 終了処理
void Cleanup()
{
    // Xメッシュを解放
    if(g_pMeshTea){
        g_pMeshTea->Release();
        g_pMeshTea = NULL;
    }
    // Direct3D オブジェクトを解放
    if(g_pD3DDev){
        g_pD3DDev->Release();
        g_pD3DDev = NULL;
    }
    if(g_pD3D){
        g_pD3D->Release();
        g_pD3D = NULL;
    }
}// Cleanup

// 描画
void Draw()
{
    g_pD3DDev->Clear(0,NULL,D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(0,0,0),1.0f,0);
    g_pD3DDev->BeginScene();
    // ワールド行列設定(ティーポットの回転用)
    static int roll = 0;
    D3DXMATRIX matWorld;
    D3DXMatrixRotationY(&matWorld,(float)roll/180*D3DX_PI);
    g_pD3DDev->SetTransform(D3DTS_WORLD,&matWorld);
    roll += 5;
    if(roll >= 360){
        roll = 0;
    }
    // ティーポットの描画
    g_pMeshTea->DrawSubset(0);
    g_pD3DDev->EndScene();
    g_pD3DDev->Present(NULL,NULL,NULL,NULL);
}// Draw

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    {
    case WM_CREATE:
        Initialize(hWnd);           // 初期設定
        SetTimer(hWnd,1,100,NULL);  // タイマー設定
        break;
        
    case WM_TIMER:
        Draw();                     // オブジェクトの描画
        break;
        
    case WM_KEYDOWN:
        switch ( wParam )
        {
        case VK_ESCAPE:             // [ESC] キーが押されると終了
            SendMessage(hWnd, WM_CLOSE, 0, 0);
            break;
        }
        break;
        
    case WM_CLOSE:
        KillTimer(hWnd,1);
        DestroyWindow(hWnd);
        Cleanup();                  // 終了処理
        PostQuitMessage(0);
        break;

    default:
        return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }
    return 0;
}// WndProc

int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR lpCmdLine,int nCmdShow)
{
    上のサンプルに同じ
}// WinMain
	
トップへ 前へ 次へ

 メッシュ

DrawPrimitiveUP() を使うよりもメッシュで最適化してから、DrawSubset() する方が高速に描画できる
#include <d3dx9.h>

#pragma comment(lib,"d3d9.lib")
#pragma comment(lib,"d3dx9.lib")

#define MYWNDTITLE      "DX9_Basis5"
#define MYWNDCLASS      "CLASS_DX9_Basis5"
#define WIDTH           320             // 画面の横のサイズ
#define HEIGHT          240             // 画面の縦のサイズ

LPDIRECT3D9             g_pD3D = NULL;
LPDIRECT3DDEVICE9       g_pD3DDev = NULL;
D3DPRESENT_PARAMETERS   g_d3dpp;
LPD3DXMESH              g_pMesh = NULL; // メッシュ
LPDIRECT3DTEXTURE9      g_pTex = NULL;  // テクスチャー

// メッシュ作成
void Create_CubeMesh()
{
    const int   v_num = 8;  // 頂点数
    const int   f_num = 12; // 面数
    // 頂点座標
    D3DXVECTOR3 vtx[v_num] =    {D3DXVECTOR3(0.5f,0.5f,-0.5f),D3DXVECTOR3(0.5f,0.5f,0.5f),
                                D3DXVECTOR3(-0.5f,0.5f,0.5f),D3DXVECTOR3(-0.5f,0.5f,-0.5f),
                                D3DXVECTOR3(0.5f,-0.5f,-0.5f),D3DXVECTOR3(0.5f,-0.5f,0.5f),
                                D3DXVECTOR3(-0.5f,-0.5f,0.5f),D3DXVECTOR3(-0.5f,-0.5f,-0.5f)};
    // テクスチャ座標
    D3DXVECTOR2 tex[v_num] =    {D3DXVECTOR2(1,0),D3DXVECTOR2(1,0),D3DXVECTOR2(0,0),D3DXVECTOR2(0,0),
                                D3DXVECTOR2(1,1),D3DXVECTOR2(1,1),D3DXVECTOR2(0,1),D3DXVECTOR2(0,1)};
    // 各面を構成する頂点番号
    int     face[f_num][3] =    {{3,2,1},{3,1,0},{0,1,5},{0,5,4},{1,2,6},{1,6,5},
                                {2,3,7},{2,7,6},{3,0,4},{3,4,7},{4,5,6},{4,6,7}};
    BYTE    *pBuf1 = NULL;
    WORD    *pBuf2 = NULL;
    DWORD   *pBuf3 = NULL;
    DWORD   dwFVF1 = D3DFVF_XYZ | D3DFVF_TEX1;
    DWORD   dwFVF2 = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1;
    int     i;
    
    // メッシュオブジェクト作成
    D3DXCreateMeshFVF(f_num, v_num, D3DXMESH_MANAGED, dwFVF1, g_pD3DDev, &g_pMesh);
    // 頂点情報設定
    g_pMesh->LockVertexBuffer(D3DLOCK_DISCARD | D3DLOCK_DONOTWAIT, (LPVOID*)&pBuf1);
    for(i=0; i<v_num; i++){
        memcpy(pBuf1, &vtx[i], sizeof(D3DXVECTOR3));
        pBuf1 += sizeof(D3DXVECTOR3);
        if(dwFVF1 & D3DFVF_TEX1){
            memcpy(pBuf1, &tex[i], sizeof(D3DXVECTOR2));
            pBuf1 += sizeof(D3DXVECTOR2);
        }
    }
    g_pMesh->UnlockVertexBuffer();
    // 面を構成する座標番号の設定
    g_pMesh->LockIndexBuffer(D3DLOCK_DISCARD | D3DLOCK_DONOTWAIT, (LPVOID*)&pBuf2);
    for(i=0; i<f_num; i++){
        *pBuf2 ++ = face[i][0];
        *pBuf2 ++ = face[i][1];
        *pBuf2 ++ = face[i][2];
    }
    g_pMesh->UnlockIndexBuffer();
    // 属性バッファ設定
    g_pMesh->LockAttributeBuffer(D3DLOCK_DISCARD | D3DLOCK_DONOTWAIT, &pBuf3);
    for(i=0; i<f_num; i++){
        *pBuf3 ++ = 0;
    }
    g_pMesh->UnlockAttributeBuffer();
    // 属性テーブル設定
    D3DXATTRIBUTERANGE attr;
    attr.AttribId    = 0;
    attr.FaceStart   = 0;
    attr.FaceCount   = f_num;
    attr.VertexStart = 0;
    attr.VertexCount = v_num;
    g_pMesh->SetAttributeTable(&attr, 1);
    // 頂点法線追加
    LPD3DXMESH pTempMesh = NULL;
    g_pMesh->CloneMeshFVF(0L, dwFVF2, g_pD3DDev, &pTempMesh);
    g_pMesh->Release();
    g_pMesh = NULL;
    if(pTempMesh)  g_pMesh = pTempMesh;
    D3DXComputeNormals(g_pMesh, NULL);
    // メッシュ最適化(描画速度向上)
    g_pMesh->OptimizeInplace(
                        D3DXMESHOPT_COMPACT | D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_IGNOREVERTS |
                        D3DXMESHOPT_VERTEXCACHE | D3DXMESHOPT_DEVICEINDEPENDENT,
                        NULL, NULL, NULL, NULL );
}// Create_CubeMesh

// 照明設定
void Set_Light()
{
    D3DXVECTOR3 vecDir;
    D3DLIGHT9   light;
    
    ZeroMemory( &light, sizeof(D3DLIGHT9) );
    light.Type      = D3DLIGHT_DIRECTIONAL;
    light.Diffuse.r = 1.0f;
    light.Diffuse.g = 1.0f;
    light.Diffuse.b = 1.0f;
    vecDir = D3DXVECTOR3(0.866025f,-0.5f,0.5f);
    D3DXVec3Normalize((D3DXVECTOR3*)&light.Direction, &vecDir);
    
    g_pD3DDev->SetLight(0, &light);
    g_pD3DDev->LightEnable(0, TRUE);
    g_pD3DDev->SetRenderState(D3DRS_AMBIENT, 0x00909090);
}// Set_Light

// マテリアル設定
void Set_Material()
{
    D3DMATERIAL9    mtrl;
    
    ZeroMemory(&mtrl, sizeof(D3DMATERIAL9));
    mtrl.Diffuse.a = 1.0f;
    mtrl.Diffuse.r = 1.0;
    mtrl.Diffuse.g = 1.0;
    mtrl.Diffuse.b = 1.0;
    mtrl.Ambient = mtrl.Diffuse;
    g_pD3DDev->SetMaterial(&mtrl);
}// Set_Material

// 初期設定
HRESULT Initialize(HWND hWnd)
{
    // Direct3D9 を作成
    g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
    
    ZeroMemory( &g_d3dpp, sizeof(g_d3dpp) );
    g_d3dpp.Windowed = TRUE;
    g_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    g_d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
    g_d3dpp.EnableAutoDepthStencil = TRUE;
    g_d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
//  g_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
    
    // D3D9Device を作成
    g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
                                      D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                      &g_d3dpp, &g_pD3DDev );
    // カリング設定
    g_pD3DDev->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
    // Zバッファ有効化
    g_pD3DDev->SetRenderState(D3DRS_ZENABLE, TRUE);
    // ビュー行列設定
    D3DXMATRIX matView;
    D3DXMatrixLookAtLH(&matView,&D3DXVECTOR3(0,0,-2.5f),&D3DXVECTOR3(0,0,0),&D3DXVECTOR3(0,1,0));
    g_pD3DDev->SetTransform(D3DTS_VIEW,&matView);
    // プロジェクション行列設定
    D3DXMATRIX matProj;
    D3DXMatrixPerspectiveFovLH(&matProj,D3DX_PI/4,(float)WIDTH/HEIGHT,0.01f,10.0f);
    g_pD3DDev->SetTransform(D3DTS_PROJECTION,&matProj);
    // メッシュ作成
    Create_CubeMesh();
    // カレント ディレクトリーを実行ファイルのディレクトリーに設定
    char path[MAX_PATH];
    GetModuleFileName(NULL,path,sizeof(path));
    char *p = strrchr(path, '\\');
    if(p){
        strcpy(p, "");
        SetCurrentDirectory(path);
    }
    // テクスチャー設定
    D3DXCreateTextureFromFile(g_pD3DDev, "tex1.png", &g_pTex);
    // 照明設定
    Set_Light();
    // マテリアル設定
    Set_Material();
    
    return S_OK;
}// Initialize

// 終了処理
void Cleanup()
{
    // メッシュを解放
    if(g_pMesh){
        g_pMesh->Release();
        g_pMesh = NULL;
    }
    // テクスチャーを解放
    if(g_pTex){
        g_pTex->Release();
        g_pTex = NULL;
    }
    // Direct3D オブジェクトを解放
    if(g_pD3DDev){
        g_pD3DDev->Release();
        g_pD3DDev = NULL;
    }
    if(g_pD3D){
        g_pD3D->Release();
        g_pD3D = NULL;
    }
}// Cleanup

// 描画
void Draw()
{
    // 画面クリア
    g_pD3DDev->Clear(0,NULL,D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(0,0,0),1.0f,0);
    // 描画開始
    g_pD3DDev->BeginScene();
    // テクスチャー適用
    if(g_pTex)
        g_pD3DDev->SetTexture(0, g_pTex);
    // メッシュ描画
    if(g_pMesh)
        g_pMesh->DrawSubset(0);
    // Y軸方向回転
    static float roll = 0;
    D3DXMATRIX  matRY;
    D3DXMatrixRotationY(&matRY, roll/180*D3DX_PI);
    g_pD3DDev->SetTransform(D3DTS_WORLD, &matRY);
    roll += 1;
    if(roll >= 360)
        roll = 0;
    // 描画終了
    g_pD3DDev->EndScene();
    // テクスチャー解除
    g_pD3DDev->SetTexture(0, NULL);
    // 画面フリップ
    g_pD3DDev->Present(NULL,NULL,NULL,NULL);
}// Draw

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    上のサンプルに同じ
}// WndProc

int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR lpCmdLine,int nCmdShow)
{
    上のサンプルに同じ
}// WinMain

	
トップへ 前へ 次へ

 宣言子

メッシュでは、柔軟な頂点フォーマット (FVF) の代わりに宣言子を使う事ができる。
Direct3D10 以降では、宣言子しか使えなくなった。
#include <d3dx9.h>

#pragma comment(lib,"d3d9.lib")
#pragma comment(lib,"d3dx9.lib")

#define MYWNDTITLE      "DX9_Basis6"
#define MYWNDCLASS      "CLASS_DX9_Basis6"
#define WIDTH           320             // 画面の横のサイズ
#define HEIGHT          240             // 画面の縦のサイズ

LPDIRECT3D9             g_pD3D = NULL;
LPDIRECT3DDEVICE9       g_pD3DDev = NULL;
D3DPRESENT_PARAMETERS   g_d3dpp;
LPD3DXMESH              g_pMesh = NULL; // メッシュ情報
LPDIRECT3DTEXTURE9      g_pTex = NULL;  // テクスチャー

// メッシュ作成
void Create_CubeMesh()
{
    const int   v_num = 8;  // 頂点数
    const int   f_num = 12; // 面数
    // 頂点座標
    D3DXVECTOR3 vtx[v_num] =    {D3DXVECTOR3(0.5f,0.5f,-0.5f),D3DXVECTOR3(0.5f,0.5f,0.5f),
                                D3DXVECTOR3(-0.5f,0.5f,0.5f),D3DXVECTOR3(-0.5f,0.5f,-0.5f),
                                D3DXVECTOR3(0.5f,-0.5f,-0.5f),D3DXVECTOR3(0.5f,-0.5f,0.5f),
                                D3DXVECTOR3(-0.5f,-0.5f,0.5f),D3DXVECTOR3(-0.5f,-0.5f,-0.5f)};
    // テクスチャ座標
    D3DXVECTOR2 tex[v_num] =    {D3DXVECTOR2(1,0),D3DXVECTOR2(1,0),D3DXVECTOR2(0,0),D3DXVECTOR2(0,0),
                                D3DXVECTOR2(1,1),D3DXVECTOR2(1,1),D3DXVECTOR2(0,1),D3DXVECTOR2(0,1)};
    // 各面を構成する頂点番号
    int     face[f_num][3] =    {{3,2,1},{3,1,0},{0,1,5},{0,5,4},{1,2,6},{1,6,5},
                                {2,3,7},{2,7,6},{3,0,4},{3,4,7},{4,5,6},{4,6,7}};
    // 宣言子
    const D3DVERTEXELEMENT9 decl[] =
    {
        {0,  0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
        {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,   0},
        {0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
        D3DDECL_END()
    };
    BYTE    *pBuf1 = NULL;
    WORD    *pBuf2 = NULL;
    DWORD   *pBuf3 = NULL;
    DWORD   dwFVF1 = D3DFVF_XYZ | D3DFVF_TEX1;
    int     i;
    
    // メッシュオブジェクト作成
    D3DXCreateMeshFVF(f_num, v_num, D3DXMESH_MANAGED, dwFVF1, g_pD3DDev, &g_pMesh);
    // 頂点情報設定
    g_pMesh->LockVertexBuffer(D3DLOCK_DISCARD | D3DLOCK_DONOTWAIT, (LPVOID*)&pBuf1);
    for(i=0; i<v_num; i++){
        memcpy(pBuf1, &vtx[i], sizeof(D3DXVECTOR3));
        pBuf1 += sizeof(D3DXVECTOR3);
        if(dwFVF1 & D3DFVF_TEX1){
            memcpy(pBuf1, &tex[i], sizeof(D3DXVECTOR2));
            pBuf1 += sizeof(D3DXVECTOR2);
        }
    }
    g_pMesh->UnlockVertexBuffer();
    // 面を構成する座標番号の設定
    g_pMesh->LockIndexBuffer(D3DLOCK_DISCARD | D3DLOCK_DONOTWAIT, (LPVOID*)&pBuf2);
    for(i=0; i<f_num; i++){
        *pBuf2 ++ = face[i][0];
        *pBuf2 ++ = face[i][1];
        *pBuf2 ++ = face[i][2];
    }
    g_pMesh->UnlockIndexBuffer();
    // 属性バッファ設定
    g_pMesh->LockAttributeBuffer(D3DLOCK_DISCARD | D3DLOCK_DONOTWAIT, &pBuf3);
    for(i=0; i<f_num; i++){
        *pBuf3 ++ = 0;
    }
    g_pMesh->UnlockAttributeBuffer();
    // 属性テーブル設定
    D3DXATTRIBUTERANGE attr;
    attr.AttribId    = 0;
    attr.FaceStart   = 0;
    attr.FaceCount   = f_num;
    attr.VertexStart = 0;
    attr.VertexCount = v_num;
    g_pMesh->SetAttributeTable(&attr, 1);
    // 頂点法線追加
    LPD3DXMESH pTempMesh = NULL;
    g_pMesh->CloneMesh(NULL, decl, g_pD3DDev, &pTempMesh);
    g_pMesh->Release();
    g_pMesh = NULL;
    if(pTempMesh)  g_pMesh = pTempMesh;
    D3DXComputeNormals(g_pMesh, NULL);
    // メッシュ最適化(描画速度向上)
    g_pMesh->OptimizeInplace(
                        D3DXMESHOPT_COMPACT | D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_IGNOREVERTS |
                        D3DXMESHOPT_VERTEXCACHE | D3DXMESHOPT_DEVICEINDEPENDENT,
                        NULL, NULL, NULL, NULL );
}// Create_CubeMesh

// 照明設定
void Set_Light()
{
    上のサンプルに同じ
}// Set_Light

// マテリアル設定
void Set_Material()
{
    上のサンプルに同じ
}// Set_Material

// 初期設定
HRESULT Initialize(HWND hWnd)
{
    上のサンプルに同じ
}// Initialize

// 終了処理
void Cleanup()
{
    上のサンプルに同じ
}// Cleanup

// 描画
void Draw()
{
    上のサンプルに同じ
}// Draw

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    上のサンプルに同じ
}// WndProc

int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR lpCmdLine,int nCmdShow)
{
    上のサンプルに同じ
}// WinMain
	
トップへ 前へ 次へ

 頂点シェーダ

プログラマブルシェーダには、頂点シェーダとピクセルシェーダがあり、
また、それぞれにプログラミング手法として、
アセンブリ言語のような LLSL (Low Level Shader Language)と
C言語のような HLSL (High Level Shader Language)とがある。
以下のサンプルでは、HLSLを使っている。
頂点シェーダは、固定機能も使える上に、ピクセルシェーダも合わせると、
頂点単位のライティングやバンプマッピングも使えるようになる。
頂点シェーダは、頂点ごとに透視変換を行うため、行列設定は不要である。
頂点色設定も可能であるため、場合によっては、照明、マテリアル、テクスチャ設定も不要になる。
シェーダの説明は、「DirectX 逆引き大全500の極意」が分かりやすい。
#include <d3dx9.h>

#pragma comment(lib,"d3d9.lib")
#pragma comment(lib,"d3dx9.lib")

#define MYWNDTITLE      "DX9_Basis7"
#define MYWNDCLASS      "CLASS_DX9_Basis7"
#define WIDTH           320     // 画面の横のサイズ
#define HEIGHT          240     // 画面の縦のサイズ

const char g_szEffect[] = 
"struct VS_IN"
"{"
    "float4 Pos    : POSITION;" // 頂点座標
    "float3 Normal : NORMAL;"   // 頂点法線ベクトル
"};"

"struct VS_OUT"
"{"
    "float4 Pos    : POSITION;" // 頂点座標
    "float4 Color  : COLOR;"    // 頂点色
"};"

"float4x4 matWorld;"    // ワールド行列
"float4x4 matAll;"      // 透視変換行列
"float3   v3Light;"     // 照明の向き

// 頂点シェーダ関数
"VS_OUT VS(VS_IN In)"
"{"
    "VS_OUT Out;"
    "float3 Normal;"
    // 頂点法線をワールド変換
    "Normal    = normalize(mul(In.Normal, matWorld));"
    // 頂点座標を透視変換
    "Out.Pos   = mul(In.Pos, matAll);"
    // Lambert 照明モデルで頂点色算出
    "Out.Color = saturate(dot(Normal, v3Light));"
    "return Out;"
"}"

"technique T0"
"{"
    "pass P0"
    "{"
        // 関数をコンパイルして頂点シェーダに渡す
        "VertexShader = compile vs_2_0 VS();"
    "}"
"}";

LPDIRECT3D9             g_pD3D = NULL;
LPDIRECT3DDEVICE9       g_pD3DDev = NULL;
D3DPRESENT_PARAMETERS   g_d3dpp;
LPD3DXMESH              g_pMeshTea = NULL;      // Xメッシュオブジェクト
LPD3DXEFFECT            g_pEffect = NULL;       // エフェクトオブジェクト
D3DXVECTOR3             g_posLook(0,0,-5.0f);   // 視点
D3DXVECTOR3             g_posLookAt(0,0,0);     // 注視点
D3DXMATRIX              g_matProj,g_matView;

// 初期設定
HRESULT Initialize(HWND hWnd)
{
    // Direct3D9 作成
    g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
    
    ZeroMemory( &g_d3dpp, sizeof(g_d3dpp) );
    g_d3dpp.Windowed = TRUE;
    g_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    g_d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
    g_d3dpp.EnableAutoDepthStencil = TRUE;
    g_d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
//  g_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
    
    // D3D9Device 作成
    g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
                          D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                          &g_d3dpp, &g_pD3DDev );
    
    // カリング設定
    g_pD3DDev->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
    // Zバッファ有効化
    g_pD3DDev->SetRenderState(D3DRS_ZENABLE, TRUE);
    // ビュー行列作成
    D3DXMatrixLookAtLH(&g_matView, &g_posLook, &g_posLookAt, &D3DXVECTOR3(0,1,0));
    // プロジェクション行列作成
    D3DXMatrixPerspectiveFovLH(&g_matProj, D3DX_PI/4, (float)WIDTH/HEIGHT, 0.01f, 10.0f);
    // ティーポット作成
    D3DXCreateTeapot(g_pD3DDev, &g_pMeshTea, NULL);
    // エフェクト読み込み
    D3DXCreateEffect(g_pD3DDev, g_szEffect, strlen(g_szEffect),
                    NULL, NULL, 0, NULL, &g_pEffect, NULL);
    // テクニック選択
    if(g_pEffect){
        g_pEffect->SetTechnique("T0");
    }
    return S_OK;
}// Initialize

// 終了処理
void Cleanup()
{
    // Xメッシュを解放
    if(g_pMeshTea){
        g_pMeshTea->Release();
        g_pMeshTea = NULL;
    }
    // エフェクトを解放
    if(g_pEffect){
        g_pEffect->Release();
        g_pEffect = NULL;
    }
    // Direct3D オブジェクトを解放
    if(g_pD3DDev){
        g_pD3DDev->Release();
        g_pD3DDev = NULL;
    }
    if(g_pD3D){
        g_pD3D->Release();
        g_pD3D = NULL;
    }
}// Cleanup

// 描画
void Draw()
{
    if(!g_pEffect){
        return;
    }
    g_pD3DDev->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0);
    g_pD3DDev->BeginScene();
    // ワールド変換行列作成
    static int roll = 0;
    D3DXMATRIX matWorld;
    D3DXMatrixRotationY(&matWorld, (float)roll/180*D3DX_PI);
    // ワールド変換行列を頂点シェーダに送信
    g_pEffect->SetMatrix("matWorld", &matWorld);
    // 透視変換行列を頂点シェーダに送信
    g_pEffect->SetMatrix("matAll", &(matWorld * g_matView * g_matProj));
    // 照明の方向を頂点シェーダに送信
    g_pEffect->SetVector("v3Light", &D3DXVECTOR4(-0.866025f,0.5f,-0.5f,0.0f));
    // 回転角度更新
    roll += 5;
    if(roll >= 360){
        roll = 0;
    }
    // ティーポットの描画
    UINT iPassCount;
    g_pEffect->Begin(&iPassCount, 0);
    g_pEffect->Pass(0);
    g_pMeshTea->DrawSubset(0);
    g_pEffect->End();
    // 描画終了
    g_pD3DDev->EndScene();
    // 画面フリップ
    g_pD3DDev->Present(NULL, NULL, NULL, NULL);
}// Draw

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    上のサンプルに同じ
}// WndProc

int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR lpCmdLine,int nCmdShow)
{
    上のサンプルに同じ
}// WinMain

	
トップへ 前へ 次へ

 ピクセル シェーダ

頂点シェーダが頂点情報を設定するのに対し、ピクセルシェーダは画素ごとの色値を設定する。
頂点シェーダの実行後、ピクセルシェーダが実行される。
#include <d3dx9.h>

#pragma comment(lib,"d3d9.lib")
#pragma comment(lib,"d3dx9.lib")

#define MYWNDTITLE      "DX9_Basis8"
#define MYWNDCLASS      "CLASS_DX9_Basis8"
#define WIDTH           320     // 画面の横のサイズ
#define HEIGHT          240     // 画面の縦のサイズ

const char g_szEffect[] = 
"struct VS_IN"  // 頂点シェーダ関数入力用構造体
"{"
    "float4 Pos    : POSITION;"     // 頂点座標
    "float3 Normal : NORMAL;"       // 頂点法線ベクトル
    "float2 Tex    : TEXCOORD0;"    // テクスチャー座標
"};"

"struct VS_OUT" // 頂点シェーダ関数出力用構造体
"{"
    "float4 Pos    : POSITION;"     // 頂点座標
    "float4 Color  : COLOR;"        // 頂点色
    "float2 Tex    : TEXCOORD0;"    // テクスチャー座標
"};"

"struct PS_IN"  // ピクセルシェーダ関数入力用構造体
"{"
    "float4 Color  : COLOR;"        // 頂点色
    "float2 Tex    : TEXCOORD0;"    // テクスチャー座標
"};"

"float4x4 matWorld;"    // ワールド行列
"float4x4 matAll;"      // 透視変換行列
"float3   v3Light;"     // 照明の向き
"texture  texMain;"     // テクスチャー

"sampler MainSampler = sampler_state"
"{"
    "Texture   = <texMain>;"
    "MinFilter = LINEAR;"
    "MagFilter = LINEAR;"
    "MipFilter = NONE;"
"};"

// 頂点シェーダ関数
"VS_OUT VS(VS_IN In)"
"{"
    "VS_OUT Out;"
    "float3 Normal;"
    // 頂点法線をワールド変換
    "Normal    = normalize(mul(In.Normal, matWorld));"
    // 頂点座標を透視変換
    "Out.Pos   = mul(In.Pos, matAll);"
    // Lambert 照明モデルで頂点色算出
    "Out.Color = saturate(dot(Normal, v3Light));"
    // テクスチャー座標
    "Out.Tex   = In.Tex;"
    "return Out;"
"}"

// ピクセルシェーダ関数
"float4 PS(PS_IN In) : COLOR"
"{"
    // 頂点色にテクスチャー色を追加して返す
    "return (In.Color + tex2D(MainSampler, In.Tex));"
"}"

"technique T0"
"{"
    "pass P0"
    "{"
        // VS関数をコンパイルして頂点シェーダに渡す
        "VertexShader = compile vs_2_0 VS();"
        // PS関数をコンパイルしてピクセルシェーダに渡す
        "PixelShader  = compile ps_2_0 PS();"
    "}"
"}";

LPDIRECT3D9             g_pD3D = NULL;
LPDIRECT3DDEVICE9       g_pD3DDev = NULL;
D3DPRESENT_PARAMETERS   g_d3dpp;
LPD3DXMESH              g_pMesh = NULL;         // Xメッシュオブジェクト
LPDIRECT3DTEXTURE9      g_pTex = NULL;          // テクスチャー
LPD3DXEFFECT            g_pEffect = NULL;       // エフェクトオブジェクト
D3DXVECTOR3             g_posLook(0,0,-2.0f);   // 視点
D3DXVECTOR3             g_posLookAt(0,0,0);     // 注視点
D3DXMATRIX              g_matProj,g_matView;

// メッシュ作成
void Create_CubeMesh()
{
    上のサンプルに同じ
}// Create_CubeMesh

// 初期設定
HRESULT Initialize(HWND hWnd)
{
    // Direct3D9 作成
    g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
    
    ZeroMemory( &g_d3dpp, sizeof(g_d3dpp) );
    g_d3dpp.Windowed = TRUE;
    g_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    g_d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
    g_d3dpp.EnableAutoDepthStencil = TRUE;
    g_d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
//  g_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
    
    // D3D9Device 作成
    g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
                          D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                          &g_d3dpp, &g_pD3DDev );
    
    // カリング設定
    g_pD3DDev->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
    // Zバッファ有効化
    g_pD3DDev->SetRenderState(D3DRS_ZENABLE, TRUE);
    // ビュー行列作成
    D3DXMatrixLookAtLH(&g_matView, &g_posLook, &g_posLookAt, &D3DXVECTOR3(0,1,0));
    // プロジェクション行列作成
    D3DXMatrixPerspectiveFovLH(&g_matProj, D3DX_PI/4, (float)WIDTH/HEIGHT, 0.01f, 10.0f);
    // メッシュ作成
    Create_CubeMesh();
    // エフェクト読み込み
    D3DXCreateEffect(g_pD3DDev, g_szEffect, strlen(g_szEffect),
                    NULL, NULL, 0, NULL, &g_pEffect, NULL);
    // テクニック選択
    if(g_pEffect){
        g_pEffect->SetTechnique("T0");
    }
    // カレント ディレクトリーを実行ファイルのディレクトリーに設定
    char path[MAX_PATH];
    GetModuleFileName(NULL,path,sizeof(path));
    char *p = strrchr(path, '\\');
    if(p){
        strcpy(p, "");
        SetCurrentDirectory(path);
    }
    // テクスチャー設定
    D3DXCreateTextureFromFile(g_pD3DDev, "tex1.png", &g_pTex);
    
    return S_OK;
}// Initialize

// 終了処理
void Cleanup()
{
    // Xメッシュを解放
    if(g_pMesh){
        g_pMesh->Release();
        g_pMesh = NULL;
    }
    // エフェクトを解放
    if(g_pEffect){
        g_pEffect->Release();
        g_pEffect = NULL;
    }
    // テクスチャーを解放
    if(g_pTex){
        g_pTex->Release();
        g_pTex = NULL;
    }
    // Direct3D オブジェクトを解放
    if(g_pD3DDev){
        g_pD3DDev->Release();
        g_pD3DDev = NULL;
    }
    if(g_pD3D){
        g_pD3D->Release();
        g_pD3D = NULL;
    }
}// Cleanup

// 描画
void Draw()
{
    if(!g_pEffect){
        return;
    }
    g_pD3DDev->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0);
    g_pD3DDev->BeginScene();
    // ワールド行列作成
    static int roll = 0;
    D3DXMATRIX matWorld;
    D3DXMatrixRotationY(&matWorld, (float)roll/180*D3DX_PI);
    // ワールド変換行列をシェーダに送信
    g_pEffect->SetMatrix("matWorld", &matWorld);
    // 透視変換行列をシェーダに送信
    g_pEffect->SetMatrix("matAll", &(matWorld * g_matView * g_matProj));
    // 照明の方向をシェーダに送信
    g_pEffect->SetVector("v3Light", &D3DXVECTOR4(-0.866025f,0.5f,-0.5f,0));
    // テクスチャーをシェーダに送信
    g_pEffect->SetTexture("texMain", g_pTex);
    // 回転角度更新
    roll += 5;
    if(roll >= 360){
        roll = 0;
    }
    // メッシュ描画
    UINT iPassCount;
    g_pEffect->Begin(&iPassCount, 0);
    g_pEffect->Pass(0);
    g_pMesh->DrawSubset(0);
    g_pEffect->End();
    // 描画終了
    g_pD3DDev->EndScene();
    // 画面フリップ
    g_pD3DDev->Present(NULL, NULL, NULL, NULL);
}// Draw

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    上のサンプルに同じ
}// WndProc

int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR lpCmdLine,int nCmdShow)
{
    上のサンプルに同じ
}// WinMain
	
トップへ 前へ 次へ

 

 
	
トップへ 前へ 次へ

 

 
	
トップへ 前へ 次へ

 

 
	
トップへ 前へ 次へ

 

 
	
トップへ 前へ 次へ

 

 
	
トップへ 前へ 次へ

 

 
	
トップへ 前へ 次へ

 

 
	
トップへ 前へ 次へ