【问题标题】:gluPerspective code messyglu透视代码乱七八糟
【发布时间】:2014-01-11 01:57:12
【问题描述】:

我对 gluPerspective 函数很好奇。当我看到这个函数的代码很乱时,我正在为我的引擎翻译代码。

void glhPerspectivef2(float *matrix, float fovyInDegrees, float aspectRatio,
                  float znear, float zfar)
{
    float ymax, xmax;
    float temp, temp2, temp3, temp4;
    ymax = znear * tanf(fovyInDegrees * M_PI / 360.0);
    //ymin = -ymax;
    //xmin = -ymax * aspectRatio;
    xmax = ymax * aspectRatio;
    glhFrustumf2(matrix, -xmax, xmax, -ymax, ymax, znear, zfar);
}

为什么它会创建 temp、temp2、temp3 和 temp4?为什么有注释代码?我想是指定glFrustum的一些参数。但是,为什么 xmin = -ymax * aspectRatio; 并不是 xmin = -max;

【问题讨论】:

    标签: opengl perspective glu


    【解决方案1】:

    您是否在此 Wiki 页面上获得此代码:http://www.opengl.org/wiki/GluPerspective_code

    为什么会创建 temp、temp2、temp3 和 temp4?

    是的,未使用的变量。很可能是从glhFrustumf2 实现中复制而来的。

    为什么会有注释代码?我想是指定glFrustum的一些参数。

    是的,可能是为了解释传递给函数glhFrustumf2的参数值。

    但是,为什么 xmin = -ymax * aspectRatio;而不是 xmin = -max;

    是的,xmin = -xmax 是正确的,并且避免了重复。

    我通常采用类似的方法:透视是根据截锥体实现的,截锥体本身是通过简单地设置矩阵的所有系数来实现的(这允许隐藏存储格式,即行优先与列优先) .与 OpenGL 手册页中相同的参数命名约定也有助于您以后需要查阅代码。

    void
    setPerspectiveMatrix4x4f(float fovy, float aspect, float zNear, float zFar, float* m)
    {
        const float bottom = -zNear * tanf(0.5f * fovy * M_PI / 180.0f);
        const float top    = -bottom;
    
        const float left   = aspect * bottom;
        const float right  = -left;
    
        setFrustumMatrix4x4f(left, right, bottom, top zNear, zFar, m);
    }
    
    void
    setFrustumMatrix4x4f(float left, float right, float bottom, float top, float zNear, float zFar, float* m)
    {
        const float dx = right - left;
        const float dy = top - bottom;
        const float dz = zFar - zNear;
    
        const float mx = 0.5f * (left + right);
        const float my = 0.5f * (bottom + top);
        const float mz = 0.5f * (zNear + zFar);
    
        const float n = zNear;
        const float nf = zNear * zFar;
    
        setMatrix4x4f(2.0f * n / dx,          0.0f,  2.0f * mx / dx,           0.0f,
                               0.0f, 2.0f * n / dy,  2.0f * my / dy,           0.0f,
                               0.0f,          0.0f, -2.0f * mz / dz, -2.0f * nf / dz,
                               0.0f,          0.0f,           -1.0f,           0.0f,
                      m);
    }
    
    void
    setMatrix4x4f(float m00, float m01, float m02, float m03,
                  float m10, float m11, float m12, float m13,
                  float m20, float m21, float m22, float m23,
                  float m30, float m31, float m32, float m33,
                  float* m)
    {
        // Fill m with m00, ... in row-major or column-major order
    }
    

    【讨论】:

      【解决方案2】:

      我不知道你从哪里得到这个函数......但如果你真的想计算透视矩阵,你可以这样做。

      下面的m 定义为float m[16]; 并且zero() 函数将m 中的所有浮点数设置为0.0f

      void perspective(const float &fovy, const float &aspect, const float &zNear, const float &zFar)
      {
          float range = tanf(fovy / 2.0f) * zNear;
          float sx = (2.0f * zNear) / (range * aspect + range * aspect);
          float sy = zNear / range;
          float sz = -(zFar + zNear) / (zFar - zNear);
          float pz = -(2.0f * zFar * zNear) / (zFar - zNear);
      
          zero();
      
          m[0] = sx;
          m[5] = sy;
          m[10] = sz;
          m[14] = pz;
          m[11] = -1.0f;
      }
      

      【讨论】:

      • 除非我很遗憾地误解了事情,否则这一行:float sx = (2.0f * zNear) / (range * aspect + range * aspect);可以这样替换:float sx = zNear / (range * aspect);
      • 你能解释一下这段代码之间的差异,它将矩阵的 5 个元素设置为非零值,而其他代码(例如 opengl.org/wiki/GluPerspective_code,将 7 个元素设置为非零值)。看起来好像您以行优先顺序省略了元素 8 和 9。
      • @GrahamAsher 透视矩阵与平截头体矩阵不同,所以我们不需要它们。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-12
      • 1970-01-01
      • 1970-01-01
      • 2019-08-16
      • 1970-01-01
      • 2014-11-29
      相关资源
      最近更新 更多