我正在使用LWJGL和着色器来尝试翻译我在着色器程序中绘制的所有内容。 我使用4乘4矩阵
1,0,0,x,
0,1,0,y,
0,0,1,z,
0,0,0,1
其中x,y,z是我用来翻译的值。然后我用
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex * transformMatrix
其中transformMatrix是一个统一的mat4,我从上面的矩阵得到。 它可以精确地转换x和y,但不能转换为z轴(向前和向后)。
矩阵或着色器方法是错误的吗? (或两者兼有)
如何解决此问题,使其翻译为glTranslatef
?感谢
答案 0 :(得分:2)
矩阵本身看起来不错。请记住,OpenGL默认使用列主要存储作为矩阵,因此当您指定矩阵时,此矩阵的元素将按此顺序排序:
{1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
x, y, z, 1.0f}
如果您想在代码中坚持使用行主要顺序,您还可以将GL_TRUE
指定为glUniformMatrix4fv()
'的第3个参数(转置)。
看起来你被困在两个不同级别的OpenGL之间。为了说明这一点,让我对OpenGL的一些主要演变阶段进行编号。以下不是官方术语,我刚刚完成了。
与OpenGL版本匹配:
您的代码片段表明您正在使用Stage 2,并且正在尝试迁移到Stage 3.在此过程中,您在两者之间创建了一个可疑的混合。根据您想要的方向,解决方案是不同的。
只要您在着色器(gl_ModelViewProjectionMatrix
)中使用固定函数矩阵堆栈中的矩阵,最简单的解决方案就是完全使用它。
因此,要翻译,请调用glTranslatef()
,它会为您的模型视图矩阵添加一个转换,然后在GLSL代码中使用gl_ModelViewProjectionMatrix
和类似的内置变量进行访问。
使用您尝试使用的方法,最合理的解决方案是在内置gl_ModelViewProjectionMatrix
之前将额外的转换矩阵与向量相乘:
gl_Position = gl_ModelViewProjectionMatrix * transformMatrix * gl_Vertex;
您需要注意,这会在模型视图转换中的所有其他模型转换之前应用之前的其他转换。假设您还使用固定函数调用指定了旋转:
glRotatef(...);
此轮换是模型视图矩阵的一部分,现在将应用于您添加的翻译。因此,您将旋转翻译的坐标,这可能不是您想要的。
使用这种方法,在其他模型转换后,没有好的方法来应用翻译。你基本上需要的是:
gl_ProjectionMatrix * gl_ViewMatrix * transformMatrix * gl_ModelMatrix * gl_Vertex;
但由于视图和模型矩阵在固定功能状态下组合,因此无法实现。
为了获得完全的灵活性以及与当前Core Profile的兼容性,您需要停止使用固定功能状态,以及相应的GLSL内置变量,如gl_ModelViewProjectionMatrix
。为此,您需要在着色器代码中将所需的所有矩阵指定为统一变量。这使您可以完全控制使用的矩阵,以及如何在GLSL代码中应用它们。
例如,如果您只需要翻译,则无需使用完整矩阵。您可以使用vec3
作为制服,只需将其添加到位置矢量。
完全可编程方法的主要缺点是您不能再使用glRotatef()
,gluLookAt
和gluPerspective()
等便捷功能。有些开源库可以提供替代品,如果您愿意,也可以自己编写类似的功能。您也不再拥有矩阵堆栈,因此如果您依赖于转换层次结构,则需要在自己的代码中使用更多逻辑。