最近将我的DestinyMatrix图形接口用DirectX实现了一遍,过程中接口又进化了一次,现在可以像WoW一样选择使用那个API来渲染WoW的场景,觉得挺不错的.又用HLSL实现了一次骨骼动画:
struct VS_INPUT
{
float3 position : POSITION;
float2 texCoord : TEXCOORD0;
float4 weight : BLENDWEIGHT;
float4 bone : BLENDINDICES;
};
struct VS_OUTPUT
{
float4 position : POSITION;
float2 texCoord : TEXCOORD0;
float4 color : COLOR;
};
uniform matrix modelViewProj;
uniform matrix boneMatrices[60];
void main(in VS_INPUT inVert, out VS_OUTPUT outVert)
{
float4 blendVertex = float4(0.0f, 0.0f, 0.0f, 0.0f);
float4 blendWeight = inVert.weight;
int4 blendBone = int4(inVert.bone);
for(int i = 0; i < 4; i++)
{
if(blendWeight.x > 0.0f)
{
blendVertex += mul(float4(inVert.position, 1.0f), boneMatrices[blendBone.x]) * blendWeight.x;
blendBone = blendBone.yzwx;
blendWeight = blendWeight.yzwx;
}
}
outVert.position = mul(blendVertex, modelViewProj);
outVert.texCoord = inVert.texCoord;
outVert.color = float4(1.0, 1.0f, 1.0f, 1.0f);
} 对比HLSL和GLSL,
1.OpenGL里的顶点属性attribute在DirectX里是通过SetStreamSource设置进去,感觉OpenGL的顶点attribute的思想更灵活.
2.为了实现接口,DirectX使用了多流模式与OpenGL的glXXXPointer保持思想上的兼容.
3.GLSL和Cg的顶点计算是标准数学的mul(mat, v),而HLSL是mul(v, mat),我调试了很久才发现 :(
4.HLSL的modelViewProj需要外部程序使用LPD3DXCONSTANTTABLE设置Matrix变量,而GLSL是内置的变量不需要外部传入.