Shader - Effect file control

按照书上的顺序(一般来说,写教程式的书籍,最重要的莫过于顺序,一本好书他章节排序能让你很好的理解内容)在经过 Vertex Shader 与

Pixel Shader 之后,就是书上的最后一章 Effects Framework (我参考的是《DirectX 9.0 游戏开发编程基础》这本书,第二次看了),这个后缀名

通常被命名为 "xxx.fx" 的文件,将之前所学习的渲染状态控制的灵活性完全释放出来,在这个文件中不仅能包含 Vertex Shader,也能够包含Pixel -

Shader,而且还能对 Fixed Pipeline 进行控制,DX SDK 的帮助文档中有一副对 Effects Frramework 进行描述的图示,如下:



PS:这就是Effects能操控的阶段,这释放了所有封闭的操作,程序员可以操作到更微小的 “元素” 以至于更好的控制渲染效果、效率。


利用书上的《LightAndTexture》来作为实例程序:


// File name : EffectsControl.fx
// Author : Dormy.X.Cui
// Description :
//

matrix worldMat;
matrix viewMat;
matrix projMat;

texture mountainTex;

// Texture sampler
sampler S0 = sampler_state
{
	Texture		= (mountainTex);
	MinFilter	= ANISOTROPIC;
	MagFilter	= ANISOTROPIC;
	MipFilter	= ANISOTROPIC;
};

technique LightAndTexture
{
	pass P0
	{
		vertexshader			= null;
		pixelshader			= null;
		fvf				= XYZ | Normal | Tex1;
		Lighting			= true;
		NormalizeNormals		= true;
		SpecularEnable			= false;

		WorldTransform[0]		= (worldMat);
		ViewTransform			= (viewMat);
		ProjectionTransform		= (projMat);

		LightType[0]			= Directional;
		LightAmbient[0]			= {0.2f,  0.2f, 0.2f, 1.0f};
		LightDiffuse[0]			= {1.0f,  1.0f, 1.0f, 1.0f};
		LightSpecular[0]		= {0.0f,  0.0f, 0.0f, 1.0f};
		LightDirection[0]		= {1.0f, -1.0f, 1.0f, 0.0f};
		LightPosition[0]		= {0.0f,  0.0f, 0.0f, 0.0f};
		LightFalloff[0]			= 0.0f;
		LightRange[0]			= 0.0f;
		LightTheta[0]			= 0.0f;
		LightPhi[0]			= 0.0f;
		LightAttenuation0[0]		= 1.0f;
		LightAttenuation1[0]		= 0.0f;
		LightAttenuation2[0]		= 0.0f;

		LightEnable[0]			= true;

		MaterialAmbient			= {1.0f, 1.0f, 1.0f, 1.0f};
		MaterialDiffuse			= {1.0f, 1.0f, 1.0f, 1.0f};
		MaterialSpecular		= {1.0f, 1.0f, 1.0f, 1.0f};
		MaterialEmissive		= {0.0f, 0.0f, 0.0f, 0.0f};
		MaterialPower			= 1.0f;

		Sampler[0] = (S0);

	}
}

这段程序里包含了一个  Technique 以及在 这个  Technique 中包含一个(也可以包含多个)Pass(通常被称作渲染通道),如你所见,在渲染通道的一开始我们

就声明了不使用 Vertex Shader  & Pixel Shader ,而使用固定渲染管线中已有的材质与灯光处理。


效果文件编写完成后,我们转回 Application 中来调用对效果文件进行编译的API,以及从常量表中取出需要初始化的常量。


代码如下:

ID3DXBuffer *pError = NULL;

	hr = ::D3DXCreateEffectFromFile(::g_pd3dDevice, L"..\\Shader\\EffectsControl.fx",
					  NULL, NULL,
					  D3DXSHADER_DEBUG | D3DXSHADER_ENABLE_BACKWARDS_COMPATIBILITY,
					  NULL, &::g_pEffect, &pError);

	if( FAILED(hr) )
	{
		::MessageBox(NULL, L"Call D3DXCreateEffectFromFromFile() - failed !", NULL, 0);

		if( pError )
		{
			::MessageBoxA(NULL, (char*)pError->GetBufferPointer(), NULL, 0);
			Demo::Release<ID3DXBuffer*>(pError);
			return E_FAIL;
		}
	}

	
	g_hWorldMatrixHandle	= ::g_pEffect->GetParameterByName(NULL, "worldMat");
	g_hViewMatrixHandle	= ::g_pEffect->GetParameterByName(NULL, "viewMat");
	g_hProjMatrixHandle	= ::g_pEffect->GetParameterByName(NULL, "projMat");
	g_hTexHandle		= ::g_pEffect->GetParameterByName(NULL, "mountainTex");
	g_hLightTexTechHandle	= ::g_pEffect->GetTechniqueByName("LightAndTexture");

	D3DXMATRIXA16 tmp_world;
	D3DXMATRIXA16 tmp_proj;

	::D3DXMatrixIdentity(&tmp_world);
	::D3DXMatrixPerspectiveFovLH(&tmp_proj, D3DX_PI * 0.25f, (float)(WND_WIDTH)/(float)(WND_HEIGHT), 1.0f, 1000.0f);

	g_pEffect->SetMatrix(::g_hWorldMatrixHandle, &tmp_world);
	g_pEffect->SetMatrix(::g_hProjMatrixHandle, &tmp_proj);

	LPDIRECT3DTEXTURE9 pTex = NULL;

	hr = ::D3DXCreateTextureFromFile(::g_pd3dDevice, L"..\\Res\\Terrain_3x_diffcol.jpg", &pTex);

	if( FAILED(hr) )
	{
		::MessageBox(NULL, L"Call D3DXCreateTextureFromFile() - failed !", NULL, 0);
		return E_FAIL;
	}

	Demo::Release<LPDIRECT3DTEXTURE9>(pTex);

	return S_OK;

这些完成后,效果文件的操作就完成了,这样我们就能够插入一些测试性的代码,比如添加一些.X文件模型看看效果,或者自己手工填充顶点缓存构造一些简单的几何体

来测试效果,效果文件很好的管理的渲染状态,从应用程序中手工调用 SetRenderState 来进行状态的设置搬家到 "xxx.fx" 文件中统一管理材质、灯光等,并且还有Shader

的支持,这样的灵活性。






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值