应用透视矩阵时的OpenGL失真

时间:2015-04-23 23:02:33

标签: c opengl

我有一个只绘制立方体的程序。当应用诸如旋转缩放等变换时,程序可以工作。当我尝试应用任何透视矩阵(如透视,平截头体或正交)时,立方体会以不确定的方式变形。令我感到困惑的是,为什么程序在使用其他转换时工作正常,但在应用任何类型的透视图时会中断。

此外,当我在glUniformMatrix4fv中将GL_TRUE参数更改为GL_FALSE时,立方体停止在屏幕上移动,但仍然有奇怪的失真。这是显示功能。只是应用透视会产生相同的失真。

%dopar%

我不相信它在我的透视功能中,因为ortho和frustum做同样的事情,但透视代码在下面。

void display()
{
    vec4 e2 = { 0.0, 0.0, 1.0, 0.0};
    vec4 at = { 0.0, 0.0, 0.0, 0.0 };
    vec4 up = { 0.0, 1.0, 0.0, 0.0 }; 

    mat4 rx = RotateX(theta);
    mat4 ry = RotateY(theta);
    mat4 ps = Perspective(zoom*45.0, aspect, 0.5, 10.0);
    mat4 rxry = multiplymat4(rx, ry);

    mat4 mv = LookAt(e2, at, up); 
    glUniformMatrix4fv( ModelView, 1, GL_TRUE, &mv.m[0][0] );

    mat4 p = multiplymat4(rxry,ps);
    glUniformMatrix4fv(projection, 1, GL_TRUE, &p.m[0][0]);
} 

顶点着色器

mat4 Perspective(float fovy, float aspect, float zNear, float zFar)
{
    float top = tan(fovy*DegreesToRadians/2) * zNear;
    float right = top * aspect;

    mat4 c = ZERO_MATRIX;
    c.m[0][0] = zNear/right;
    c.m[1][1] = zNear/top;
    c.m[2][2] = -(zFar + zNear)/(zFar - zNear);
    c.m[2][3] = -2.0*zFar*zNear/(zFar - zNear);
    c.m[3][2] = -1.0;
    c.m[3][3] = 0.0;
    return c;
}

2 个答案:

答案 0 :(得分:0)

我可以发现两个地方似乎我错了。

1)您将透视矩阵与旋转矩阵相乘。为什么?如果你想做相机移动,它们必须在lookAt矩阵中完成。所以,我建议这个简单的代码:

mat4 ps = Perspective(zoom*45.0, aspect, 0.5, 10.0);
glUniformMatrix4fv(projection, 1, GL_TRUE, &ps.m[0][0]);

2)透视分割是由GPU自动完成的,这样看来我的顶点着色器也是错的:

gl_Position = projection*ModelView*vPosition;
color = vec4( vColor);

答案 1 :(得分:0)

矩阵乘法顺序很重要,从我看到你的p矩阵应该是

mat4 p = multiplymat4(ps, rxry);

虽然逻辑旋转属于视图矩阵。

此外,/ vPosition.w可能在着色器中不执行任何操作,因为除非您实际提供了4维位置数据,否则w等于1.0。你的顶点着色器也不需要透视分割。