码迷,mamicode.com
首页 > 其他好文 > 详细

透视投影矩阵的构建

时间:2015-04-07 23:35:22      阅读:592      评论:0      收藏:0      [点我收藏+]

标签:3d   matrix   

透视投影矩阵的构建

投影矩阵最终建立的是一个平截头体(也可以称为台),在这种变换下呈现远小近大的效果。这里我将我学到知识记录下来,以后备忘用。

蒋彩阳原创文章,首发地址:http://blog.csdn.net/gamesdev/article/details/44926299。欢迎同行前来探讨。

       首先是使用OpenGL的glFrustum函数,它要求传入的是前后、左右、上下等参数,这要求这个平截头体是轴对称的。由它构成的矩阵是为:

技术分享

       如果我们使用的不是glFrustum,而是glPerspetive,那么它的公式就更加简单了:

技术分享

       我们可以借助Qt来一下验证:

#include <math.h>
#include <QDebug>
#include <QCoreApplication>
#include <QVector3D>
#include <QMatrix4x4>

qreal deg2Rad( qreal deg )
{
    return deg * 2 * M_PI / 180.0f;
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    qreal fov = 45.0;
    qreal aspectRatio = 16.0 / 9.0;
    qreal near = 0.5;
    qreal far = 500.0;

    qreal left = -near * tan( deg2Rad( fov ) / 2.0 ) * aspectRatio;
    qreal right = near * tan( deg2Rad( fov ) / 2.0 ) * aspectRatio;
    qreal bottom = -near * tan( deg2Rad( fov ) / 2.0 );
    qreal top = near * tan( deg2Rad( fov ) / 2.0 );

    QMatrix4x4 matrix;
    matrix.frustum( left, right, bottom, top, near, far );

    qDebug( ) << "The normal perspective matrix is: " << matrix;

    QMatrix4x4 matrix_2;
    float* d = matrix_2.data( );
    d[0] = 2 * near / ( right - left );
    d[1] = 0.0;
    d[2] = 0.0;
    d[3] = 0.0;
    d[4] = 0.0;
    d[5] = 2 * near / ( top - bottom );
    d[6] = 0.0;
    d[7] = 0.0;
    d[8] = ( right + left ) / ( right - left );
    d[9] = ( top + bottom ) / ( top - bottom );
    d[10] = -( far + near ) / ( far - near );
    d[11] = -1;
    d[12] = 0.0;
    d[13] = 0.0;
    d[14] = -2 * far * near / ( far - near );
    d[15] = 0.0;

    qDebug( ) << "The user manipulated matrix is: " << matrix_2;

    QMatrix4x4 matrix_3;
    d = matrix_3.data( );
    d[0] = 1.0 / ( tan( deg2Rad( fov ) / 2.0 ) * aspectRatio );
    d[1] = 0.0;
    d[2] = 0.0;
    d[3] = 0.0;
    d[4] = 0.0;
    d[5] = 1.0 / ( tan( deg2Rad( fov ) / 2.0 ) );
    d[6] = 0.0;
    d[7] = 0.0;
    d[8] = 0.0;
    d[9] = 0.0;
    d[10] = -( far + near ) / ( far - near );
    d[11] = -1;
    d[12] = 0.0;
    d[13] = 0.0;
    d[14] = -2 * far * near / ( far - near );
    d[15] = 0.0;

    qDebug( ) << "Another user manipulated matrix is: " << matrix_3;

    return a.exec( );
}

注意:和OpenGL一样,矩阵是列主序的,所以上述公式在赋值的时候要一列一列地读,先读第一列的四个数,然后第二列……运行结果如下:

技术分享

透视投影矩阵的构建

标签:3d   matrix   

原文地址:http://blog.csdn.net/gamesdev/article/details/44926299

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!