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

今までのソースでは、ベクトルの単位ベクトルか(ノーマライズ)はしてなかったのですが、今回はやっています。