HLSL 法線テスト+平行色光
VertexShaderからHLSLの方に変更、まずは「VertexShader 法線テスト+平行色光源」を作ってみます。
G9lib.h
#pragma once #pragma once #include "windows.h" #include <d3d9.h> #include <d3dx9.h> class G9lib { public: G9lib(void); public: ~G9lib(void); private: LPDIRECT3D9 pD3D; LPDIRECT3DDEVICE9 pD3DDevice; D3DPRESENT_PARAMETERS d3dppApp; LPDIRECT3DVERTEXBUFFER9 gVBuffer; LPD3DXEFFECT pEffect; public: bool Init( HWND hwnd ); void Exit( void ); void TestDraw(); }; //頂点フォーマット struct D3DVERNORMAL { float x,y,z; // 座標 float nx,ny,nz; // 法線 enum { FVF = D3DFVF_XYZ | D3DFVF_NORMAL } ; };
G9lib.cpp
#include "G9lib.h" #include "../VertexShader/Model.h" //ライブラリ登録 #pragma comment(lib, "d3d9.lib") #pragma comment(lib, "d3dx9.lib") G9lib::G9lib(void) { pD3D = NULL; pD3DDevice = NULL; gVBuffer = NULL; pEffect = NULL; } G9lib::~G9lib(void) { if (pD3D) { pD3D->Release(); pD3D = NULL; } if (pD3DDevice) { pD3DDevice->Release(); pD3DDevice = NULL; } if( gVBuffer ){ gVBuffer->Release(); gVBuffer = NULL; } if( pEffect ){ pEffect->Release(); pEffect = NULL; } } //------------------------------------------------------------------------------ //■ライブラリ初期化 //------------------------------------------------------------------------------ bool G9lib::Init( HWND hwnd ) { // Direct3Dオブジェクトの取得 pD3D = Direct3DCreate9(D3D_SDK_VERSION); if (pD3D == NULL) { MessageBox( hwnd, L"Direct3Dの初期化に失敗しました、DirectX 9.0がインストールされているか確認してください。",L"Base",MB_OK | MB_ICONSTOP); return FALSE; } // 現在のディスプレイモードを得る D3DDISPLAYMODE dmode; if (FAILED(pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &dmode))) { MessageBox( hwnd, L"ディスプレイモードの取得に失敗しました。",L"Base",MB_OK | MB_ICONSTOP); return FALSE; } // バックサーフェースのフォーマットをコピーして使用する ZeroMemory(&d3dppApp, sizeof(d3dppApp)); d3dppApp.Windowed = TRUE; // ウィンドウモード d3dppApp.SwapEffect = D3DSWAPEFFECT_DISCARD; // 垂直同期でフリップ d3dppApp.BackBufferCount = 1; d3dppApp.BackBufferFormat = dmode.Format; d3dppApp.EnableAutoDepthStencil = TRUE; d3dppApp.AutoDepthStencilFormat= D3DFMT_D16; // デバイスの作成 if (FAILED(pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dppApp, &pD3DDevice))) { if (FAILED(pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dppApp, &pD3DDevice))) { MessageBox( hwnd, L"デバイスの作成に失敗しました、画面モードが16ビットあるいは32ビットになっていることを確認してください。",L"Base",MB_OK | MB_ICONSTOP); return FALSE; } } //------------------------------------------------------------------- // シェーダー読み込み if( FAILED( D3DXCreateEffectFromFile( pD3DDevice, L"vsample01.fx", NULL, NULL, 0, NULL, &pEffect, NULL ) ) ) return FALSE; //----------------------------------------- // モデル登録 void *lpVertices; HRESULT hr; hr = pD3DDevice->CreateVertexBuffer(sizeof(modelData), 0, D3DVERNORMAL::FVF, D3DPOOL_DEFAULT, &gVBuffer, NULL ); if (FAILED(hr)) return FALSE; // 頂点バッファをコピー hr = gVBuffer->Lock(0, sizeof(modelData), (LPVOID*)&lpVertices, 0); if (FAILED(hr)) return FALSE; memcpy(lpVertices, modelData, sizeof(modelData)); gVBuffer->Unlock(); return TRUE; } //------------------------------------------------------------------------------ //■ライブラリ開放 //------------------------------------------------------------------------------ void G9lib::Exit( void ) { } //------------------------------------------------------------------------------ //■テスト描画 //------------------------------------------------------------------------------ void G9lib::TestDraw() { D3DXMATRIX matView; D3DXMATRIX matProj; D3DXMATRIX matWorld; pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0, 0); pD3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW ); // 片面 pD3DDevice->SetRenderState( D3DRS_LIGHTING,FALSE); // 光源無効 pD3DDevice->BeginScene(); //----------------------------------------- D3DXMatrixRotationY( &matWorld,timeGetTime()/5000.0f ); D3DXMatrixLookAtLH(&matView,&D3DXVECTOR3(0.0f, -5.0f, 30.0f), // カメラの位置を表す3次元ベクトル &D3DXVECTOR3(0.0f, 0.0f, 0.0f), // カメラの注視点を表す3次元ベクトル &D3DXVECTOR3(0.0f, 1.0f, 0.0f)); // 上方向を表す3次元ベクトル D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 10.0f, 2000.0f ); //----------------------------------------- pEffect->SetMatrix( "mWVP", &(matWorld * matView * matProj) ); // マトリクスの登録 //----------------------------------------- // シェーダー設定 UINT nPasses; D3DXHANDLE hTechnique = pEffect->GetTechniqueByName( "TShader" ); pEffect->SetTechnique( hTechnique ); pEffect->Begin( &nPasses, 0 ); pEffect->BeginPass(0); // 今回はパスは1個決めうちです。 { // モデル登録 pD3DDevice->SetFVF(D3DVERNORMAL::FVF); pD3DDevice->SetStreamSource( 0, gVBuffer, 0, sizeof(D3DVERNORMAL) ); pD3DDevice->DrawPrimitive( D3DPT_TRIANGLELIST , 0, sizeof(modelData)/sizeof(D3DVERNORMAL)/3 ); } pEffect->EndPass(); pEffect->End(); //----------------------------------------- // 描画 pD3DDevice->EndScene(); pD3DDevice->Present(NULL, NULL, NULL, NULL); }
今までと異なりマトリックスを渡すとき 転置行列 に変換しなくてよいので楽です
そしてHLSLのシェーダープログラム「vsample01.fx」
//--------------------------------------------------------------- float4x4 mWVP; struct VS_OUTPUT { float4 Pos : POSITION; float4 Col : COLOR0; }; //--------------------------------------------------------------- VS_OUTPUT VS( float4 Pos : POSITION, float3 Normal : NORMAL ) { VS_OUTPUT Out = (VS_OUTPUT)0; float4 diffuse = { 0.0f, 1.0f, 0.0f, 0.0f}; // 光源の色 float3 dir = { 0.707f, 0.707f,0.0f}; // 光源の向き Out.Pos = mul(Pos, mWVP); Out.Col = diffuse * ( mul(dir, mul(Normal, mWVP)) * 0.5f + 0.5f); return Out; } //--------------------------------------------------------------- technique TShader { pass P0 { VertexShader= compile vs_1_1 VS(); } }