HLSL顶点着色器


昨日不可追, 今日尤可为.勤奋,炽诚,不忘初心

手机淘宝二维码 扫描      

或者打开连接:程序设计开发 ,掌声鼓励,欢迎光临.


 

 

顶点着色器替代了固定渲染管线中的 变幻 光照 阶段.

实现步骤:

1.在文本文件里编写顶点着色器代码(HLSL语言)

2.编译着色器代码(D3DXCompileShaderFromFile)

3.创建顶点着色器(CreateVertexShader)

4.获取HLSL语言中变量句柄(GetConstantByName)

5.根据句柄给HLSL语言中的变量传值(ID3DXConstTable->Setxxx)??

在文本文件里写顶点着色器代码:

//----------------------------------begin VertexShader.txt--------------------------------------------
//世界-观察 矩阵
matrix g_world_view;
//世界-观察-投影 矩阵
matrix g_world_view_proj;

//颜色
vector g_color;
//光线方向
vector g_dir_to_light;

//输入
struct VTIN
{
 vector pos :POSITION; //输入:位置
 vector normal : NORMAL; //输入:法线
};

//输出
struct VTOUT
{
 vector pos : POSITION; //输出:位置
 float2 uv : TEXCOORD; //输出:纹理坐标
 vector diffuse : COLOR; //输出:颜色
};

//函数入口
VTOUT main(VTIN input)
{
 //初始化输出结构
 VTOUT output = (VTOUT)0;
 
 //pos由建模空间-世界空间-观察空间-投影空间 变幻
 output.pos = mul(input.pos, g_world_view_proj);
 
 //转换光线和法线到观察空间,设置w分量为0
 //确保没有缩放变幻,因为缩放会弄乱法线的方向
 g_dir_to_light.w = 0.0f;
 input.normal.w = 0.0f;
 g_dir_to_light = mul(g_dir_to_light, g_world_view);
 input.normal   = mul(input.normal,   g_world_view);
 
 //计算出uv
 //其实只要用到纹理的x(即u)就行了
 float u = dot(g_dir_to_light, input.normal);
 //如果u<0.0f,说明角度大于90°,接受不到光线,so
 if(u < 0.0f)
 {
  u = 0.0f;
 }
 float v = 0.5f; //纹理图片y轴像素(0.0f~1.0f)
 
 output.uv.x = u;
 output.uv.y = v;
 
 output.diffuse = g_color; 
 
 return output;
}
//----------------------------------end VertexShader.txt--------------------------------------------
<pre class="cpp" name="code">//vs中程序代码:

#define MESH_TEAPOT		0
#define MESH_SPHERE		1
#define MESH_TORUS		2
#define MESH_CYLINDER	3
	//-----------顶点着色器相关的变量------------------
	IDirect3DVertexShader9* m_VertexShader;
	ID3DXConstantTable*		m_ConstantTable;
	IDirect3DTexture9*		m_ShadeTexture;

	ID3DXMesh*				m_Meshes[4];
	D3DXMATRIX				m_WorldMatrices[4];
	D3DXVECTOR4				m_MeshColors[4];

	D3DXMATRIX				m_ProjMatrix;

	D3DXHANDLE				m_WorldViewHandle;
	D3DXHANDLE				m_WorldViewProjHandle;
	D3DXHANDLE				m_ColorHandle;
	D3DXHANDLE				m_DirLightHandle;
	
	
	//setup: main函数中调用一次
	void Setup()
	{
		//创建模型们: 茶壶 圆球 圆环 圆桶
		D3DXCreateTeapot(D3DDevice, &m_Meshes[MESH_TEAPOT], NULL);
		D3DXCreateSphere(D3DDevice, 1.0f, 20, 20, &m_Meshes[MESH_SPHERE], NULL);
		D3DXCreateTorus(D3DDevice, 0.5f, 1.0f, 20, 20, &m_Meshes[MESH_TORUS], NULL);
		D3DXCreateCylinder(D3DDevice, 0.5f, 0.5f, 2.0f, 20, 20, &m_Meshes[MESH_CYLINDER], NULL);
		
		//模型们的在世界中的矩阵:
		D3DXMatrixTranslation(&m_WorldMatrices[MESH_TEAPOT], 0.0f, 2.0f, 0.0f);
		D3DXMatrixTranslation(&m_WorldMatrices[MESH_SPHERE], 0.0f, -2.0f, 0.0f);
		D3DXMatrixTranslation(&m_WorldMatrices[MESH_TORUS], -3.0f, 0.0f, 0.0f);
		D3DXMatrixTranslation(&m_WorldMatrices[MESH_CYLINDER], 3.0f, 0.0f, 0.0f);
		//模型们的颜色:
		m_MeshColors[MESH_TEAPOT] = D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f);
		m_MeshColors[MESH_SPHERE] = D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f);
		m_MeshColors[MESH_TORUS] = D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f);
		m_MeshColors[MESH_CYLINDER] = D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f);

		//编译着色器:
		ID3DXBuffer*	shader_buffer;
		ID3DXBuffer*	error_buffer;
		HRESULT hr = D3DXCompileShaderFromFile(L"D:\\VertexShader.txt", NULL, NULL, "main", "vs_1_1",
			D3DXSHADER_ENABLE_BACKWARDS_COMPATIBILITY,
			&shader_buffer, &error_buffer, &m_ConstantTable);
		// 输出错误信息:
		if (error_buffer)
		{
			string str = (char*)error_buffer->GetBufferPointer();
			MessageBox(NULL, Common::StringToWString(str).c_str(), L"ERROR", MB_OK);
			//safe_release<ID3DXBuffer*>(error_buffer);
		}
		if (FAILED(hr))
		{
			MessageBox(NULL, L"D3DXCreateEffectFromFile() - FAILED", L"ERROR", MB_OK);
		}
		//创建顶点着色器
		hr = D3DDevice()CreateVertexShader((DWORD*)shader_buffer->GetBufferPointer(), &m_VertexShader);
		if (FAILED(hr))
		{
			MessageBox(NULL, L"CreateVertexShader - FAILED", L"ERROR", MB_OK);
		}
		//释放
		//safe_release<ID3DXBuffer*>(shader_buffer);

		//加载纹理:
		D3DXCreateTextureFromFile(D3DDevice, L"D:\\pic1.png", &m_ShadeTexture);
		//设置状态属性:
		D3DDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
		D3DDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
		D3DDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);//禁用过滤

		//获取常量句柄
		m_WorldViewHandle = m_ConstantTable->GetConstantByName(NULL, "g_world_view");
		m_WorldViewProjHandle = m_ConstantTable->GetConstantByName(NULL, "g_world_view_proj");
		m_ColorHandle = m_ConstantTable->GetConstantByName(NULL, "g_color");
		m_DirLightHandle = m_ConstantTable->GetConstantByName(NULL, "g_dir_to_light");

		// set shader constants
		D3DXVECTOR4 dir_to_light(-0.57f, 0.57f, -0.57f, 0.0f);
		m_ConstantTable->SetVector(D3DDevice, m_DirLightHandle, &dir_to_light);
		m_ConstantTable->SetDefaults(D3DDevice);

		//设置投影矩阵
		RECT rt;
		GetClientRect(hwnd, &rt);
		D3DXMatrixPerspectiveFovLH(&m_ProjMatrix, D3DX_PI / 4.0f, (float)rt.right / rt.bottom, 1.0f, 1000.0f);
	}
	
//display: 在消息循环中调用,时时更新
	void Display(float timeDelta)
	{
		static float angle = (3.0f * D3DX_PI) / 2.0f;
		static float height = 5.0f;

		if (GetAsyncKeyState(VK_LEFT) & 0x8000f)
			angle -= 0.5f * timeDelta;

		if (GetAsyncKeyState(VK_RIGHT) & 0x8000f)
			angle += 0.5f * timeDelta;

		if (GetAsyncKeyState(VK_UP) & 0x8000f)
			height += 5.0f * timeDelta;

		if (GetAsyncKeyState(VK_DOWN) & 0x8000f)
			height -= 5.0f * timeDelta;

		D3DXVECTOR3 position(cosf(angle) * 7.0f, height, sinf(angle) * 7.0f);
		D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);
		D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);

		D3DXMATRIX view_matrix;
		D3DXMatrixLookAtLH(&view_matrix, &position, &target, &up);

		// render now
		D3DDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
		D3DDevice->BeginScene();
		D3DDevice->SetVertexShader(m_VertexShader);
		D3DDevice->SetTexture(0, m_ShadeTexture);

		D3DXMATRIX world_view, world_view_proj;

		for (int i = 0; i < 4; i++)
		{
			world_view = m_WorldMatrices[i] * view_matrix;
			world_view_proj = m_WorldMatrices[i] * view_matrix * m_ProjMatrix;

			m_ConstantTable->SetMatrix(D3DDevice, m_WorldViewHandle, &world_view);
			m_ConstantTable->SetMatrix(D3DDevice, m_WorldViewProjHandle, &world_view_proj);
			m_ConstantTable->SetVector(D3DDevice, m_ColorHandle, &m_MeshColors[i]);

			m_Meshes[i]->DrawSubset(0);
		}
		D3DDevice()->EndScene();
		D3DDevice()->Present(NULL, NULL, NULL, NULL);
	}

 

 

 

 

代码来自博客:天行健君子当自强不息.

效果图:当纹理图为效果图为

当纹理图为效果图为:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值