最近升级了机器,由于要等Geforce 8800降价,于是先搞了块ATI X1650XT,也方便程序的兼容性调试.
于是,很多先前写的GLSL Shader出错了.以下均以最新驱动为标准.
1.无法对uniform mat4 boneMatrices[57];数组中的单个矩阵赋值!
GLint location = glGetUniformLocationARB(m_idProg, "boneMatrices[2]");
glUniformMatrix4fvARB(location, 1, GL_TRUE, fMatrices);
取得location有效,赋值后在Shader中验证,赋值没有成功.
2.如果外部没有显式地设置纹理矩阵,则gl_TextureMatrix[0]没有定义,不是默认的单位矩阵.
3.如vec4 v; ATI没有默认初始化为vec4(0, 0, 0, 0); 而Nvidia下则有默认初始化.
4.GLSL数组的索引变量必须为编译期常数,否则:
Link successful. The GLSL vertex shader will run in software - unsupported language element used.
CPU模拟运行,速度奇慢无比.这还是ATI X1650XT级别的显卡,而NVidia 6000系列就可以支持dynamic array index了.
没有了dynamic array index,是根本无法作骨骼动画计算的,而同样的显卡下HLSL却支持dynamic array index,所以这不是显卡能力问题,是态度问题.
但严格来说,这些都不能算ATI的bug过错,他确确实实没有违背GLSL的语言标准, 最多也就是消极应对,极不友好而已.因为我去翻看这些GLSL语言标准,发现这些细节地方的描述十分含糊,基本上是可有可无,OpenGL ARB整一个官僚.
GLSL毁于ARB手.
补:
在Openg.org上发帖查问,一位哥们给出了4的优化问题,改成
vec4 blendVertex = vec4(0, 0, 0, 0);
for(int i = 0; i < 4; i++)
{
blendVertex += boneMatrices[int(bone[i])] * gl_Vertex * weight[i];
}
于是这段shader神奇地run in hardware mode了,原来是shader里的loop逻辑过于复杂导致的run in software mode,却表现在了dynamic index上,似乎只要屏蔽dynamic index就正常.