45fan.com - 路饭网

搜索: 您的位置主页 > 电脑频道 > 电脑教程 > 阅读资讯:使用编译HLSL着色器的方法

使用编译HLSL着色器的方法

2016-08-29 09:49:24 来源:www.45fan.com 【

使用编译HLSL着色器的方法

1.2 编译HLSL着色器

阅读此文表明您已同意文末的声明

1.2.1 常量表

每个着色器都有一个常量表(constant table),它用于存储着色器变量。D3DX库为我们提供了应用程序访问着色器常量表的接口ID3DXConstantTable。通过这个接口,我们可以在应用程序的代码中设置set)着色器源代码中的变量。(译者注:这里的“设置”可以理解为“为赋值”,比如上面一句也可以理解为“我们可以在应用程序的代码中为着色器源代码中的变量赋值”,下同)

我们现在就描述一个删减了的ID3DXConstantTable的方法实现的列表。完整列表请参见Direct3D文档。

1.2.1.1 获得常量句柄

为了在应用程序代码中设置着色器中的一个特定的变量,我们需要一种方法引用它。我们可以在应用程序中通过D3DXHANDLE引用着色器的一个变量。下列方法返回一个着色器中变量的D3DXHANDLE,只要给定其(译者注:“其”指着色器中的变量)名字:

D3DXHANDLE ID3DXConstantTable::GetConstantByName(

D3DXHANDLE hConstant, // scope of constant

LPCSTR pName // name of constant

);

hConstant——需要句柄承载的变量的父结构的D3DXHANDLE标识。例如,如果我们要得到一个特定结构实例的单一数据成员的句柄,我们可以传递这个结构实例的句柄进去。如果我们要获得一个顶层变量(top-level variable)的句柄,给这个参数传递0就好了。

pName——需要句柄返回的着色器源代码中的变量的名字。

例如,如果着色器中变量的名字是ViewProjMatrix,并且它是一个顶层参数,我们可以这样写:

// Get a handle to the ViewProjMatrix variable in the shader.
D3DXHANDLE h0;
h0 = ConstTable->GetConstantByName(0, "ViewProjMatrix");

1.2.1.2 设置常量

一旦应用程序获得了着色器代码中引用的特定变量的D3DXHANDLE句柄,我们就可以用ID3DXConstantTable::SetXXX方法在应用程序中设置这个变量,其中XXX代表要设置的变量的类型。例如,如果我们要设置的变量是一个vector数组,方法名就应是SetVectorArray

ID3DXConstantTable::SetXXX的一般语法形式如下:

HRESULT ID3DXConstantTable::SetXXX(
 LPDIRECT3DDEVICE9 pDevice,
 D3DXHANDLE hConstant,
 XXX value
);

n pDevice——与常量表关联的设备的指针

n hConstant——一个句柄,它引用我们正在设置的变量

n value——我们要把变量设置成的值,其中XXX替换为我们要设置的变量的类型的名字。对于有些类型(boolintfloat)我们传递一个值的拷贝a copy of the value),但是对于其它类型(vectors, matrices, structures),我们传递一个值的指针a pointer to the value)。

当我们设置一个数组的时候,SetXXX方法需要一个额外的第四个参数,它指定数组中元素的个数。例如,对于设置一个4D数组的方法,原型如下:

HRESULT ID3DXConstantTable::SetVectorArray(
 LPDIRECT3DDEVICE9 pDevice, // associated device
 D3DXHANDLE hConstant, // handle to shader variable
 CONST D3DXVECTOR4* pVector, // pointer to array
 UINT Count // number of elements in array
);

以下列表描述了我们可以用ID3DXConstantTable接口设置的类型的列表。这里假定我们有一个设定用的有效设备,和一个有效句柄。

SetBool—Used to set a Boolean value. Sample call:

bool b = true;
ConstTable->SetBool(Device, handle, b);

SetBoolArray—Used to set a Boolean array. Sample call:

bool b[3] = {true, false, true};
ConstTable->SetBoolArray(Device, handle, b, 3);

SetFloat—Used to set a float. Sample call:

float f = 3.14f;
ConstTable->SetFloat(Device, handle, f);

SetFloatArray—Used to set a float array. Sample call:

float f[2] = {1.0f, 2.0f};
ConstTable->SetFloatArray(Device, handle, f, 2);

SetInt—Used to set an integer. Sample call:

int x = 4;
ConstTable->SetInt(Device, handle, x);

SetIntArray—Used to set an integer array. Sample call:

int x[4] = {1, 2, 3, 4};
ConstTable->SetIntArray(Device, handle, x, 4);

SetMatrix—Used to set a 4 × 4 matrix. Sample call:

D3DXMATRIX M();
ConstTable->SetMatrix(Device, handle, &M);

SetMatrixArray—Used to set a 4 × 4 matrix array. Sample call:

D3DXMATRIX M[4];
// ...Initialize matrices
ConstTable->SetMatrixArray(Device, handle, M, 4);

SetMatrixPointerArray—Used to set an array of 4 × 4 matrix pointers. Sample call:

D3DXMATRIX* M[4];
// ...Allocate and initialize matrix pointers
ConstTable->SetMatrixPointerArray(Device, handle, M, 4);

SetMatrixTranspose—Used to set a transposed 4 × 4 matrix. Sample call:

D3DXMATRIX M();
D3DXMatrixTranspose(&M, &M);
ConstTable->SetMatrixTranspose(Device, handle, &M);

SetMatrixTransposeArray—Used to set an array of 4 × 4 transposed matrices. Sample call:

D3DXMATRIX M[4];
// ...Initialize matrices and transpose them.
ConstTable->SetMatrixTransposeArray(Device, handle, M, 4);

SetMatrixTransposePointerArray—Used to set an array of pointers to 4 × 4 transposed matrices. Sample call:

D3DXMATRIX* M[4];
// ...Allocate,initialize matrix pointers and transpose them.
ConstTable->SetMatrixTransposePointerArray(Device, handle, M, 4);

SetVector—Used to set a variable of type D3DXVECTOR4. Sample call:

D3DXVECTOR4 v(1.0f, 2.0f, 3.0f, 4.0f);
ConstTable->SetVector(Device, handle, &v);

SetVectorArray—Used to set a variable that is a vector array. Sample call:

D3DXVECTOR4 v[3];
// ...Initialize vectors
ConstTable->SetVectorArray(Device, handle, v, 3);

SetValue—Used to set an arbitrarily sized type, such as a structure. In the sample call, we use SetValue to set a D3DXMATRIX:

D3DXMATRIX M();
ConstTable->SetValue(Device, handle, (void*)&M, sizeof(M));

1.2.1.3 设置常量默认值

下一个方法就是设置常量为它们的默认值,这些默认值在声明时初始化。这个方法应该在应用程序建立(setup)期间被一次性调用called once)。

HRESULT ID3DXConstantTable::SetDefaults(
 LPDIRECT3DDEVICE9 pDevice
);

n pDevice——关联到常量表的设备的指针。

1.2.2 编译HLSL着色器

我们可以编译一个着色器——用我们已保存的着色器的文本文件——使用下列函数:

HRESULT D3DXCompileShaderFromFile(
 LPCSTR pSrcFile,
 CONST D3DXMACRO* pDefines,
 LPD3DXINCLUDE pInclude,
 LPCSTR pFunctionName,
 LPCSTR pTarget,
 DWORD Flags,
 LPD3DXBUFFER* ppShader,
 LPD3DXBUFFER* ppErrorMsgs,
 LPD3DXCONSTANTTABLE* ppConstantTable
);

n pSrcFile——要编译的包含着色器源代码的文本文件的文件名

n pDefines——参数可选,本书中指定为空。

n pInclude——ID3DXInclude接口指针。这个接口被设计成由应用程序实现,所以我们可以重载默认include的行为。通常,默认行为是良好,而且我们可以通过将其指定为空忽略此参数。

n pFunctionName——指定入口点函数名的字符串。例如,如果着色器的入口点函数叫做Main,我们可以给此参数传递“Main”。

n pTarget——指定要编译成的HLSL着色器源文件的版本的字符串。有效的顶点着色器版本是:vs_1_1, vs_2_0, vs_2_sw。有效的像素着色器版本是2.0,我们可以给此参数传递vs_2_0

备注:有能力编译为不同着色器版本是HLSL超越汇编语言的一个主要好处。用HLSL我们只需简单的重新编译为需要的target,便可快速移植着色器到不同版本。使用汇编,则我们可能需要手动移植代码。

n Flags——可选的编译标记,指定为0标识没有标记。有效的选项是:

l D3DXSHADER_DEBUG——通知编译器写入调试信息

l D3DXSHADER_SKIPVALIDATION——通知编译器不要做任何代码检查。此项仅用于你已知着色器能够工作时

l D3DXSHADER_SKIPOPTIMIZATION——通知编译器不要执行任何代码优化。实践中,这个选项应该仅用于调试,因为这种情况下你不希望编译器以任何方式修改代码。

n ppShader——返回已编译的着色器代码的ID3DXBuffer指针。这个已编译着色器代码将作为另一个实际创建顶点/像素着色器的函数的参数

n ppErrorMsgs——返回包含错误码和错误消息字符串的ID3DXBuffer指针

n ppConstantTable——返回包含此着色器常量表数据的ID3DXConstantTable指针

这里是一个调用D3DXCompileShaderFromFile的例子:

//
// Compile shader
//
ID3DXConstantTable* TransformConstantTable = 0;
ID3DXBuffer* shader = 0;
ID3DXBuffer* errorBuffer = 0;
hr = D3DXCompileShaderFromFile(
 "transform.txt", // shader filename
 0,
 0,
 "Main", // entry point function name
 "vs 2 0", // shader version to compile to
 D3DXSHADER_DEBUG, // debug compile
 &shader,
 &errorBuffer,
 &TransformConstantTable);
// output any error messages
if( errorBuffer )
{
 ::MessageBox(0, (char*)errorBuffer->GetBufferPointer(), 0, 0);
 d3d::Release<ID3DXBuffer*>(errorBuffer);
}
if (FAILED (hr))
{
 ::MessageBox(0, "D3DXCreateEffectFromFile() - FAILED", 0, 0);
 return false;
}

[声明]:本文译自Frank Luna的《Introduction to 3D Game Programming with DirectX 9.0》,限于译者水平,文中难免错漏之处,欢迎各位网友批评指正;本文仅用于学习交流与参考用途,不得用于任何形式的商业用途;如需转载需事先征得作者本人和译者的同意,保持文章的完整性,并注明作者、译者和出处,对于违反以上条款造成的后果,译者对此不负任何责任。我的邮箱地址是Raymond_King123@hotmail.com,欢迎热爱3D图形和游戏,并有一定图形编程经验的朋友来信交流。

 

本文地址:http://www.45fan.com/dnjc/69228.html
Tags: 效果 1.2 着色
编辑:路饭网
关于我们 | 联系我们 | 友情链接 | 网站地图 | Sitemap | App | 返回顶部