HLSL

シェーダーをアセンブラで書くと解かり辛いし再利用性も低くなってしまいます。
High Level Shader Language ( HLSL ) はC言語風で解りやすいシェーダー言語です。
他にもcg言語などがありますがWindowsではHLSLを使うのが一般的です。

HLSL.cpp

#include <d3dx9.h>
#define WINDOW_WIDTH  640 //ウインドウの幅
#define WINDOW_HEIGHT  480 //ウインドウの高さ
#define SAFE_RELEASE(x) if(x){x->Release();}

LPDIRECT3D9             g_pD3D       = NULL;//Direct3D9
LPDIRECT3DDEVICE9       g_pd3dDevice = NULL;//レンダリングデバイス

LPD3DXMESH    pMesh   = NULL;//メッシュ
D3DMATERIAL9*   pMaterials  = NULL;//マテリアル
LPDIRECT3DTEXTURE9*  pTextures  = NULL;//テクスチャ

DWORD dwNumMaterials = 0;

 LPD3DXEFFECT     m_pEffect; // ★シェーダ
 D3DXHANDLE      m_hTechnique;// ★テクニック
 D3DXHANDLE      m_hmWVP; // ★ワールド~射影行列
 LPDIRECT3DVERTEXDECLARATION9 m_pDecl; // 頂点宣言
 D3DXMATRIXA16 matWorld,matView,matProj;

HWND hwnd;
HRESULT Init()
{
 HRESULT hr;
 // ★シェーダの読み込み
    LPD3DXBUFFER pErr=NULL;
    if( FAILED( hr = D3DXCreateEffectFromFileA(
                g_pd3dDevice, "hlsl.fx", NULL, NULL,
                0 , NULL, &m_pEffect, &pErr ))){
        // シェーダの読み込みの失敗
        MessageBoxA( NULL, (LPCSTR)pErr->GetBufferPointer()
                    , "ERROR", MB_OK);
    }else{
        m_hTechnique = m_pEffect->GetTechniqueByName( "TShader" );
        m_hmWVP = m_pEffect->GetParameterByName( NULL, "mWVP" );
    }
    SAFE_RELEASE(pErr);

 return true;
}
void FrameUpDate()
{
  //ワールドトランスフォーム(絶対座標変換)
  D3DXMATRIXA16 matRotation;
  D3DXMatrixRotationY( &matWorld, timeGetTime()/3000.0f );
  D3DXMatrixRotationX( &matRotation, 0.5f );
  D3DXMatrixMultiply(&matWorld,&matWorld,&matRotation);
  // ビュートランスフォーム(視点座標変換)

     D3DXVECTOR3 vecEyePt( 0.0f, 7.0f,-3.5f ); //カメラ(視点)位置
     D3DXVECTOR3 vecLookatPt( 0.0f, 0.0f, 0.0f );//注視位置
     D3DXVECTOR3 vecUpVec( 0.0f, 1.0f, 0.0f );//上方位置
     D3DXMatrixLookAtLH( &matView, &vecEyePt, &vecLookatPt, &vecUpVec );
  // プロジェクショントランスフォーム(射影変換)
     D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 1.0f, 100.0f );

}
void ScreenDraw()
{

// 画面をクリアする
    g_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
                         0x000000ff, 1.0f, 0L );
    //シーンの開始
    if(SUCCEEDED(g_pd3dDevice->BeginScene()))
    {
  D3DXMATRIX m;
  D3DXVECTOR4 v;
  //-------------------------------------------------
   // ★シェーダの設定
   //-------------------------------------------------
   m_pEffect->SetTechnique( m_hTechnique );
   m_pEffect->Begin( NULL, 0 );
   m_pEffect->BeginPass( 0 );
  
   //-------------------------------------------------
   // ★シェーダ定数の設定
   //-------------------------------------------------
   m = matWorld * matView * matProj;
   m_pEffect->SetMatrix( m_hmWVP, &m );

   m_pEffect->SetTexture("Tex", pTextures[0]);
   //-------------------------------------------------
   // 描画
   //-------------------------------------------------
   g_pd3dDevice->SetVertexDeclaration( m_pDecl );
     for( DWORD i=0; i<dwNumMaterials; i++ )
        {
            g_pd3dDevice->SetMaterial( &pMaterials[i] );
            g_pd3dDevice->SetTexture( 0, pTextures[i] );
            pMesh->DrawSubset( i );
        }

   m_pEffect->EndPass();
   m_pEffect->End();

 
        //シーンの終了
        g_pd3dDevice->EndScene();
    }

    //バックバッファを表画面に反映させる
    g_pd3dDevice->Present( NULL, NULL, NULL, NULL );

 

}
void GetFPS()
{
  FrameUpDate();
  ScreenDraw();
  Sleep(16);
}
DWORD WINAPI MainLoop(LPVOID vdParam)
{
 while(TRUE){
  GetFPS();
 }
 return 0;
}
HRESULT InitD3D( HWND hWnd )
{
 if(NULL==(g_pD3D=Direct3DCreate9(D3D_SDK_VERSION))){return E_FAIL;}

    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory( &d3dpp, sizeof(d3dpp) );
    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
    d3dpp.BackBufferCount = 1;
    d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
    d3dpp.MultiSampleQuality = 0;
    d3dpp.EnableAutoDepthStencil = TRUE;
    d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
    d3dpp.hDeviceWindow = hWnd;
    d3dpp.Flags = 0;
    d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
 d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE ;

    if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice))){
        if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice))){
   return(E_FAIL);
        }
    }

 // Xファイルからメッシュをロードする
 LPD3DXBUFFER pD3DXMtrlBuffer = NULL;

 if( FAILED( D3DXLoadMeshFromXA( "box.x", D3DXMESH_SYSTEMMEM,
            g_pd3dDevice, NULL, &pD3DXMtrlBuffer, NULL,
   &dwNumMaterials, &pMesh ) ) )
    {
            MessageBoxA(NULL, "Xファイルの読み込みに失敗しました",NULL, MB_OK);
            return E_FAIL;
    }
 D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer();
    pMaterials = new D3DMATERIAL9[dwNumMaterials];
    pTextures  = new LPDIRECT3DTEXTURE9[dwNumMaterials];

 for( DWORD i=0; i<dwNumMaterials; i++ )
 {
  pMaterials[i] = d3dxMaterials[i].MatD3D;
        pMaterials[i].Ambient = pMaterials[i].Diffuse;
        pTextures[i] = NULL;
        if( d3dxMaterials[i].pTextureFilename != NULL &&
            lstrlenA(d3dxMaterials[i].pTextureFilename) > 0 )
        {    
            if( FAILED( D3DXCreateTextureFromFileA( g_pd3dDevice,
                                                d3dxMaterials[i].pTextureFilename,
                                                &pTextures[i] ) ) )
            {   
                MessageBoxA(NULL, "テクスチャの読み込みに失敗しました", NULL, MB_OK);
   }
        }
    }
 pD3DXMtrlBuffer->Release();


 Init();
    return S_OK;
}
LRESULT CALLBACK MsgProc(HWND hwnd , UINT msg , WPARAM wp , LPARAM lp) {
 switch (msg) {
  case WM_DESTROY:
   PostQuitMessage(0);
   return 0;
 }
 return DefWindowProc(hwnd , msg , wp , lp);
}

int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE hPrevInstance ,PSTR lpCmdLine , int nCmdShow )
{
 MSG msg;
 DWORD dwID;


    WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
                      GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
                      L"Window1", NULL };
    RegisterClassEx( &wc );

 RECT rect;
 SetRect(&rect,0,0,WINDOW_WIDTH,WINDOW_HEIGHT);
 AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);
 SetRect(&rect,0,0,rect.right-rect.left,rect.bottom-rect.top);

    hwnd = CreateWindow( L"Window1", L"HLSL",
    WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, rect.right, rect.bottom,
                              NULL, NULL, wc.hInstance, NULL );

 if (hwnd == NULL) return 0;

  timeBeginPeriod(1);

 if(SUCCEEDED(InitD3D(hwnd))){
  ShowWindow(hwnd,SW_SHOWDEFAULT);
        UpdateWindow(hwnd);

  CreateThread(NULL , 0 , MainLoop , (LPVOID)hwnd , 0 , &dwID);
  while (GetMessage(&msg , NULL , 0 , 0 )) {
  TranslateMessage(&msg);
  DispatchMessage(&msg);
 }

 }
 UnregisterClass(L"Window1",wc.hInstance);
 timeEndPeriod(1);

 SAFE_RELEASE( m_pEffect );  // シェーダ
 SAFE_RELEASE( m_pDecl );  // 頂点宣言
 SAFE_RELEASE(pMesh);
 SAFE_RELEASE(g_pd3dDevice);
    SAFE_RELEASE(g_pD3D);
 return 0;
}

hlsl.fx

//グローバル変数
float4x4 mWVP;//ローカルから射影空間への座標変換

//テクスチャ
texture Tex;
sampler Samp = sampler_state
{
 Texture =<Tex>;
 MinFilter =LINEAR;
 MagFilter =LINEAR;
 MipFilter =NONE;

 AddressU =Clamp;
 AddressV =Clamp;
};

//頂点シェーダからピクセルシェーダに渡すデータ
struct VS_OUTPUT
{
 float4 Pos : POSITION;
 float2 Tex : TEXCOORD0;
};

//頂点シェーダプログラム
VS_OUTPUT VS( float4 Pos:POSITION, float2 Tex:TEXCOORD)
{
 VS_OUTPUT Out = (VS_OUTPUT)0;//出力データ
 Out.Pos = mul(Pos, mWVP);//位置座標
 Out.Tex = Tex;//テクスチャ座標
 return Out;
}

//ピクセルシェーダプログラム
float4 PS( VS_OUTPUT In ):COLOR
{
 return tex2D( Samp, In. Tex );
}

//テクニック
technique TShader
{
 pass P0
 {
  //シェーダ
  VertexShader = compile vs_2_0 VS();
  PixelShader = compile ps_2_0 PS();
 }
}

最終更新:2009年05月20日 19:22
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。
添付ファイル