我正在使用vecmath库帮助处理矩阵数学,而我正在转换opengl程序以更好地利用glsl
。
在写完问题之后我想我有3个小问题:
display()
内的所有模型,视图和投影矩阵?即每一帧这是我在projection
的{{1}}函数中计算view
和reshape
矩阵的方法。
GLEventListener
辅助功能..
Matrix4f mProjectionMatrix = createPerspectiveProjection(
60.0f, width / height, 0.1f, 100.0f);
Matrix4f mViewMatrix = new Matrix4f();
mViewMatrix.setIdentity();
在private Matrix4f createPerspectiveProjection(float fov, float aspect, float zNear, float zFar){
Matrix4f mat = new Matrix4f();
float yScale = (float) (1 / (Math.tan(Math.toRadians(fov / 2))));
float xScale = yScale / aspect;
float frustrumLength = zFar - zNear;
mat.m00 = xScale;
mat.m11 = yScale;
mat.m22 = -((zFar + zNear) / frustrumLength);
mat.m23 = -1;
mat.m32 = -((2 * zFar * zNear) / frustrumLength);
mat.m33 = 0;
return mat;
}
的{{1}}内,我不确定后续步骤。
从概念上讲,我有以下几点,这些是我需要执行的正确步骤吗? ..
display()
这是我的顶点着色器..
GLEventListener
答案 0 :(得分:7)
我在OpenGL应用程序中保留了三个矩阵。它们是模型,查看和投影矩阵。使用制服将所有这些矩阵发送到着色器,着色器执行此操作。
gl_Position = mProj * mView * mModel * vec4(position, 1.0);
也就是说,默认情况下位置在本地对象空间中。将其与模型矩阵相乘可应用该模型的平移,旋转和缩放,并且变换后的顶点现在位于世界空间中。
现在顶点乘以视图矩阵,该矩阵应用相机的变换,如相机位置和方向。现在,顶点将位于眼睛空间中。
最后,顶点与 Projection 矩阵相乘,应用透视或正交的效果,这取决于我选择使用的内容。最后,在变换之后,顶点将处于标准化的设备坐标(范围从 -1 到 +1 ),并将由OpenGL渲染。
模型矩阵从哪里得到它的价值?
模型矩阵默认为单位矩阵。每当您只想变换实体而不是整个世界时,您将变换矩阵与模型矩阵相乘,并将结果设置为新的模型矩阵。这允许您为场景中的每个模型实例保留单独的属性。
我是否需要重置
display()
内的所有模型,视图和投影矩阵?即每一帧?
不,不。您可以创建一次矩阵,但只要客户端(即您的程序)的矩阵值发生变化,您就必须更新着色器程序中的制服。
绘制每个对象后,我是否重置模式,视图和投影矩阵?
不,不。通常,您将保留一个投影和一个视图矩阵,但场景中每个对象都有几个模型矩阵。投影通常不会在应用程序的整个过程中发生变化,因此无需重新更新。视图矩阵与您的相机一起使用,因此通常它也适用于整个场景。然而,模型矩阵对于每个对象将是不同的,因此您必须每帧更新它。
从哪里获取模型矩阵值?那是什么产生的?
有一些公式可以创建这些矩阵,就像上面的辅助方法一样,它根据视场和摄像机镜头的纵横比生成透视投影矩阵。这里很难解释所有这些公式,因此您可以看到具有此类功能的TransformUtils
类的源代码。
在我的GitHub存储库中查看我的TransformUtils类的源代码。它没有完整记录,但我认为你可以使用它们。
希望这有帮助。