【问题标题】:Why does this Perspective Projection Matrix Calculation not give the correct result?为什么这个透视投影矩阵计算没有给出正确的结果?
【发布时间】:2012-01-01 01:25:45
【问题描述】:

我无法完全弄清楚这一点。 我有一个 OpenGL 应用程序,我正在从旧的固定功能管道转换为可编程管道,并摆脱了我一直在使用的不推荐使用的功能...... 在数学方面我不是最好的,矩阵对我来说相当新。

但是,我的 ModelView 矩阵工作正常,但我似乎无法让 Perspective 矩阵正常工作。

我的意思是,我可以使用不推荐使用的固定函数,获取矩阵的值,并将其与我生成的计算值相匹配... ModelView?没问题。看法?它不匹配,我不明白为什么。

这两种方法可以通过注释掉预处理器#define USEPROJMATRIX来切换


typedef float vec_t;

const static vec_t identityMatrix[16] = { 1.0, 0.0, 0.0, 0.0, 
                                          0.0, 1.0, 0.0, 0.0, 
                                          0.0, 0.0, 1.0, 0.0, 
                                          0.0, 0.0, 0.0, 1.0 };

const static vec_t zeroMatrix[16] = { 0.0, 0.0, 0.0, 0.0,
                                      0.0, 0.0, 0.0, 0.0,
                                      0.0, 0.0, 0.0, 0.0,
                                      0.0, 0.0, 0.0, 0.0 };

const double pi = 3.1415926535897932384626433832795;

float Utils::Radians(const float& degrees)
{
    return degrees * (pi / 180);
}

vec_t* Utils::FrustumMatrix(vec_t* out_matrix, const vec_t& left, const vec_t& right, const vec_t& bottom, const vec_t& top, const vec_t& znear, const vec_t& zfar) // Replaced glFrustum()
{
    memcpy(out_matrix, zeroMatrix, 16*sizeof(vec_t));

    out_matrix[0] = (2.0 * znear) / (right - left);
    out_matrix[5] = (2.0 * znear) / (top - bottom);
    out_matrix[8] = (right + left) / (right - left);
    out_matrix[9] = (top + bottom) / (top - bottom);
    out_matrix[10] = -((zfar + znear) / (zfar - znear));
    out_matrix[11] = -1.0;
    out_matrix[14] = -((2.0 * zfar * znear) / (zfar - znear));

    return out_matrix;
}

vec_t* Utils::PerspectiveMatrix(vec_t* out_matrix, const vec_t& yFOVDegrees, const vec_t& aspectRatio, const vec_t& znear, const vec_t& zfar) // Replaces gluPerspective()
{
    vec_t range, left, right, bottom, top;

    range = tan(Radians(yFOVDegrees / 2)) * znear;
    left = -range * aspectRatio;
    right = range * aspectRatio;
    bottom = -range;
    top = range;

    return FrustumMatrix(out_matrix, left, right, bottom, top, znear, zfar);
}

#define USEPROJMATRIX
void GameLogic::OnResize(int width = 640, int height = 480)
{
    glViewport(0, 0, width, height);
    glMatrixMode(GL_PROJECTION);
#ifndef USEPROJMATRIX
    glLoadMatrixf(identityMatrix);
    gluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 1.0f, 1000.0f);
#else
    vec_t pMatrix[16];
    memcpy(pMatrix, identityMatrix, sizeof(vec_t) * 16);
    Utils::PerspectiveMatrix(pMatrix, 45.0f, (GLfloat)width / (GLfloat)height, 1.0f, 1000.0f);
    glLoadMatrixf(pMatrix);
#endif

    vec_t projectionmatrix[16];
    glGetFloatv(GL_PROJECTION_MATRIX, projectionmatrix);

    /* Matrix calculation results in projectionmatrix equalling this:
       1.8106601, 0.00000000, 0.00000000, 0.00000000, 
       0.00000000, 2.4142134, 0.00000000, 0.00000000, 
       0.00000000, 0.00000000, -1.0020020, -1.0000000,
       0.00000000, 0.00000000, -2.0020020, 0.0000000
    */
    /* GL calculation
       1.8106601, 0.00000000, 0.00000000, 0.00000000,
       0.00000000, 2.4142137, 0.00000000, 0.00000000,
       0.00000000, 0.00000000, -1.0020020, -1.0000000,
       0.00000000, 0.00000000, -2.0020020, 0.00000000
    */

    glMatrixMode(GL_MODELVIEW);
    glLoadMatrixf(identityMatrix);
}

我通过直接观察和比较矩阵值来检查我的值。 结果值列在上面的 cmets 中,我不知道为什么它们不匹配。手动计算的矩阵在视觉上扭曲了渲染场景(一个简单的立方体偏移到中心左下角),因为它没有正确定位,我相信它也被渲染得更小了。

编辑 根据尼可波拉斯的回答修正了愚蠢的错误。但是,这仍然无法正常工作。评论中的值也已更新。 编辑2 上面的代码现在可以正常工作,问题已解决。我犯了一些愚蠢的错误。

【问题讨论】:

    标签: c++ opengl matrix projection perspective


    【解决方案1】:

    这是您在gluPerspective 通话中使用的内容:

    (GLfloat)width / (GLfloat)height
    

    这是您在Utils::PerspectiveMatrix 通话中使用的内容:

    width / height
    

    第一个产生一个浮点值。第二个产生一个整数。我猜你想要第一个。

    【讨论】:

    • 这确实是我的一个愚蠢的错误。但是,问题仍然存在。数字仍然不匹配。我相信 projectionmatrix[5] 元素的轻微不匹配只是舍入误差或使用中 pi 的有效数字,但 projectionmatrix[15] 完全错误。
    • 安恩德,废话。发现了问题。初始化我的矩阵错误。问题已更正为正确的代码,感谢您指出我太盲目看不到的明显情况。 :)
    猜你喜欢
    • 1970-01-01
    • 2021-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-06
    • 2023-02-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多