多重纹理——像素着色器

     上午花了几个小时仔细研究了一下像素着色器中的多重纹理,由于对固定流水线比较熟悉,所以看这本书看的比较快。下面就来解析一下这个多重纹理,对于一些不太明白的东西也做一下讨论: 

     1、利用DirectX Caps Viewer查我的显卡(GeForce 9400 GT)支持的着色器版本,是3.0,这样最好了,支持16层纹理。对于D3DXCompileShaderFromFile()这个函数,有个参数值得注意,就是Flags,书(DirectX 9.0 游戏看法编程基础)上只讲了三种合法的编译选项,但是我们如果直接在VS上运行它的代码,发现出错,就是因为这个Flags的缘故。解决办法:查看SDK,发现其实不只有三种,DX9支持10中FLAGES,而DX10支持的更多,解决方法有二:修改ps_1_1为ps_3_0,不改变FLAGES,具体看你的显卡了;方法二是修改D3DXSHADER_DEBUG为D3DXSHADER_ENABLE_BACKWARDS_COMPATIBILITY可把1.0当做2.0编译,即向后兼容,不过这个编译项是DX10支持的,加入相应的库链接就可以。

      2、对于编译好的shader,我们用通过CreatePixelShader获得IDirectX3DPixelShader9接口(DX都是对一些接口进行操作)的指针,要通过应用程序改变设定shader(着色器)里面的变量值或初始值,我们必须使用接口ID3DConstantTable,使用下面的语句便是初始化为默认值。

MultiTexCT->SetDefaults(Device);

通过下面的语句进行设定:

HRESULT SetXXX(
  LPDIRECT3DDEVICE9 pDevice,
  D3DXHANDLE hConstant,
  XXX VALUE
);

对于纹理,第一步载入到相应的接口中:

	D3DXCreateTextureFromFile(Device, "crate.bmp", &BaseTex);
	D3DXCreateTextureFromFile(Device, "spotlight.bmp", &SpotLightTex);
	D3DXCreateTextureFromFile(Device, "text.bmp", &StringTex);

第二步得到着色器中纹理采样器的句柄:

	BaseTexHandle      = MultiTexCT->GetConstantByName(0, "BaseTex");//此BaseTex与上面的BaseTex不同,这个BaseTex是着色器里面的采样器名称,那个是纹理接口
	SpotLightTexHandle = MultiTexCT->GetConstantByName(0, "SpotLightTex");
	StringTexHandle    = MultiTexCT->GetConstantByName(0, "StringTex");

第三步是设定着色器中的采样器的值,我实验了有两种方法,个人感觉书上的更繁琐一些:

书上的,先用GetConstantDesc得到采样器的描述情况,由于描述情况包含了采用器的注册索引,具体参考课本:

	MultiTexCT->GetConstantDesc(BaseTexHandle,      &BaseTexDesc, &count);
		Device->SetSamplerState(BaseTexDesc.RegisterIndex, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
		Device->SetSamplerState(BaseTexDesc.RegisterIndex, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
		Device->SetSamplerState(BaseTexDesc.RegisterIndex, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);

第二种方法是自己无意间查SDK发现的,就是直接得到采样器的注册索引,而不通过描述情况,如下:

		// base tex
		Device->SetTexture(MultiTexCT->GetSamplerIndex(BaseTexHandle), BaseTex);
		Device->SetSamplerState(MultiTexCT->GetSamplerIndex(BaseTexHandle), D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
		Device->SetSamplerState(MultiTexCT->GetSamplerIndex(BaseTexHandle), D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
		Device->SetSamplerState(MultiTexCT->GetSamplerIndex(BaseTexHandle), D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); 
第四步就是调用来设定采样器和其绑定的纹理:
IDirect3DDevice9::SetTexture

原文地址:https://www.cnblogs.com/bite_the_bullet/p/1822313.html