着色器和效果——1.2 编译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图形和游戏,并有一定图形编程经验的朋友来信交流。

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值