VertexShader インチキ環境マッピング
テクスチャ用に「LPDIRECT3DTEXTURE9 image01」を追加します。
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; LPDIRECT3DVERTEXSHADER9 vShader; LPDIRECT3DVERTEXBUFFER9 gVBuffer; LPDIRECT3DTEXTURE9 image01; public: bool Init( HWND hwnd ); void Exit( void ); void TestDraw(); }; //頂点フォーマット struct D3DVERTEXCOR { float x,y,z; // 座標 DWORD color; // 頂点カラー enum { FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE } ; }; //頂点フォーマット 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; vShader = NULL; gVBuffer = NULL; image01 = NULL; } G9lib::~G9lib(void) { if (pD3D) { pD3D->Release(); pD3D = NULL; } if (pD3DDevice) { pD3DDevice->Release(); pD3DDevice = NULL; } if( vShader ){ vShader->Release(); vShader = NULL; } if( gVBuffer ){ gVBuffer->Release(); gVBuffer = NULL; } if( image01 ){ image01->Release(); image01 = 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; } } //------------------------------------------------------------------- LPD3DXBUFFER pVS; if (FAILED(D3DXAssembleShaderFromFile( L"vsample01.vsh",NULL,NULL,0,&pVS,NULL))) return FALSE; if(FAILED(pD3DDevice->CreateVertexShader((DWORD*)pVS->GetBufferPointer(),&vShader))) { pVS->Release(); return FALSE; } pVS->Release(); //----------------------------------------- // モデル登録 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(); //----------------------------------------- //テクスチャ読み込み if( D3DXCreateTextureFromFile(pD3DDevice, L"../VertexShader/image01.bmp", &image01 ) != D3D_OK ) image01 = NULL; 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 ); //----------------------------------------- D3DXMATRIX m; D3DXMatrixTranspose(&m,&(matWorld * matView * matProj)); //転置行列 に変換 pD3DDevice->SetVertexShaderConstantF(0,(float*)&m,4); //視点・透視変換 //----------------------------------------- pD3DDevice->SetTexture( 0, image01 ); //----------------------------------------- // モデル登録 pD3DDevice->SetVertexShader(vShader); pD3DDevice->SetFVF(D3DVERNORMAL::FVF); pD3DDevice->SetStreamSource( 0, gVBuffer, 0, sizeof(D3DVERNORMAL) ); pD3DDevice->DrawPrimitive( D3DPT_TRIANGLELIST , 0, sizeof(modelData)/sizeof(D3DVERNORMAL)/3 ); //----------------------------------------- pD3DDevice->SetTexture( 0, NULL ); //----------------------------------------- // 描画 pD3DDevice->EndScene(); pD3DDevice->Present(NULL, NULL, NULL, NULL); }
使用するテクスチャは image01.bmp
vsample01.vsh
//c0-c3 ビュー+透視変換マトリックス //c4 汎用固定値 //c5 平行光源向き //c6 光源色 //c7 ダークカラー // //v0 頂点の座標値 //v1 法線情報 vs_1_1 // バージョン命令 def c4, 0.0f, 0.5f, 1.0f, 2.0f // 汎用固定値 dcl_position v0 // 座標頂点宣言 dcl_normal v1 // 法線 m4x4 oPos, v0, c0 m3x3 r0, v1, c0 dp3 r0.w, r0, r0 rsq r1, r0.w mul r0, r0, r1 mad oT0.xy,r0.xy,c4.yy,c4.yy
今までのソースでは、ベクトルの単位ベクトルか(ノーマライズ)はしてなかったのですが、今回はやっています。