我的MVP矩阵构建器有什么问题?

时间:2016-02-08 18:02:29

标签: c++ opengl math

我在C ++中使用自己的类和数学函数,我犯了一个可怕的错误但却看不到它的位置。我代表一个带线性阵列的4x4矩阵,这是我的矩阵生成器函数:

float& Mat4x4::getRef(unsigned int row, unsigned int column)
{
    return this->data[(4 * (column)) + row];
}

void Mat4x4::set(unsigned int row, unsigned int column, float value)
{
    this->getRef(row, column) = value;
}

Mat4x4 Mat4x4::getRotationalXMatrix(Vec3 rot, bool oglform)
{
    /*
        |  1  0       0       0 |
     M = |  0  cos(A) -sin(A)  0 |
         |  0  sin(A)  cos(A)  0 |
         |  0  0       0       1 |

         standard mathematical format -- opengl wants the transposed.
    */
    Mat4x4 res = Mat4x4::identity();
    res.set(1, 1, cos(rot.getX()));
    res.set(2, 1, (-sin(rot.getX())));
    res.set(1, 2, sin(rot.getX()));
    res.set(2, 2, cos(rot.getX()));
    return oglform ? res.transposed() : res;
}

Mat4x4 Mat4x4::getRotationalYMatrix(Vec3 rot, bool oglform)
{
    /*
         |  cos(A)  0   sin(A)  0 |
     M = |  0       1   0       0 |
         | -sin(A)  0   cos(A)  0 |
         |  0       0   0       1 |

         standard mathematical format -- opengl wants the transposed.
    */
    Mat4x4 res = Mat4x4::identity();
    res.set(0, 0, cos(rot.getY()));
    res.set(2, 0, sin(rot.getY()));
    res.set(0, 2, -sin(rot.getY()));
    res.set(2, 2, cos(rot.getY()));
    return oglform ? res.transposed() : res;
}

Mat4x4 Mat4x4::getRotationalZMatrix(Vec3 rot, bool oglform)
{
    /*
        |  cos(A)  -sin(A)   0   0 |
     M = |  sin(A)   cos(A)   0   0 |
         |  0        0        1   0 |
         |  0        0        0   1 |

         standard mathematical format -- opengl wants the transposed.
    */
    Mat4x4 res = Mat4x4::identity();
    res.set(0, 0, cos(rot.getZ()));
    res.set(1, 0, -sin(rot.getZ()));
    res.set(0, 1, sin(rot.getZ()));
    res.set(1, 1, cos(rot.getZ()));
    return oglform ? res.transposed() : res;
}

Mat4x4 Mat4x4::getRotationalMatrix(Vec3 pos, bool oglform)
{
    return getRotationalXMatrix(pos, oglform) * getRotationalYMatrix(pos, oglform) * getRotationalZMatrix(pos, oglform);
}

Mat4x4 Mat4x4::getTranslationMatrix(Vec3 pos, bool oglform)
{
Mat4x4 res = Mat4x4::identity();
    res.set(3, 0, pos.getX());
    res.set(3, 1, pos.getY());
    res.set(3, 2, pos.getZ());
    return oglform ? res.transposed() : res;
}

Mat4x4 Mat4x4::getScaleMatrix(Vec3 scale, bool oglform)
{
    Mat4x4 res = Mat4x4::identity();
    res.set(0, 0, scale.getX());
    res.set(1, 1, scale.getY());
    res.set(2, 2, scale.getZ());
    return oglform ? res.transposed() : res;
}

Mat4x4 Mat4x4::lookatOGL(Vec3 eye, Vec3 centre, Vec3 up)
{
    Vec3 zaxis = (centre - eye).normalised();
    Vec3 xaxis = (up.cross(zaxis)).normalised();
    Vec3 yaxis = zaxis.cross(xaxis);
    float orient[16] = {0.0f};
    orient[0] = xaxis.getX();
    orient[1] = yaxis.getX();
    orient[2] = zaxis.getX();
    orient[3] = 0.0f;

    orient[4] = xaxis.getY();
    orient[5] = yaxis.getY();
    orient[6] = zaxis.getY();
    orient[7] = 0.0f;

    orient[8] = xaxis.getZ();
    orient[9] = yaxis.getZ();
    orient[10] = zaxis.getZ();
    orient[11] = 0.0f;

    orient[12] = 0.0f; orient[13] = 0.0f; orient[14] = 0.0f; orient[15] = 1.0f;
    Mat4x4 orientation(orient);

    float trans[16] = {0.0f};

    trans[0] = 1.0f;
    trans[1] = 0.0f;
    trans[2] = 0.0f;
    trans[3] = 0.0f;
    trans[4] = 0.0f;
    trans[5] = 1.0f;
    trans[6] = 0.0f;
    trans[7] = 0.0f;
    trans[8] = 0.0f;
    trans[9] = 0.0f;
    trans[10] = 1.0f;
    trans[11] = 0.0f;
    trans[12] = -eye.getX();
    trans[13] = -eye.getY();
    trans[14] = -eye.getZ();
    trans[15] = 1.0f;

    Mat4x4 translation(trans);

    return (translation * orientation);
}

五个重要的OpenGL矩阵:

Mat4x4 Mat4x4::getModelMatrix(Vec3 pos, Vec3 rot, Vec3 scale, bool oglform)
{
    return Mat4x4::getTranslationMatrix(pos, oglform) * Mat4x4::getRotationalMatrix(rot, oglform) * Mat4x4::getScaleMatrix(scale, oglform);
}

Mat4x4 Mat4x4::getViewMatrix(Vec3 eye, Vec3 centre, Vec3 up, bool oglform)
{
    return Mat4x4::lookatOGL(eye, centre, up);
}

Mat4x4 Mat4x4::getProjectionMatrix(float fovRad, float aspectRatio, float near, float far, bool oglformat)
{
    float tanHalfFOV = tan(fovRad / 2);
    float data[16] = {0.0f};
    Mat4x4 res(data);
    res.set(0, 0, (1/(aspectRatio * tanHalfFOV)));
    res.set(1, 1, (1/tanHalfFOV));
    res.set(2, 3, -1);

    float twotwo = -(far + near) / (far - near);
    float threetwo = -(2 * far * near) / (far - near);
    res.set(2, 2, twotwo);
    res.set(3, 2, threetwo);
    return res;
}

Mat4x4 Mat4x4::getMVMatrixOGL(Vec3 pos, Vec3 rot, Vec3 scale, Vec3 eye, Vec3 centre, Vec3 up)
{
    Mat4x4 m = Mat4x4::getModelMatrix(pos, rot, scale, true);
    Mat4x4 v = Mat4x4::getViewMatrix(eye, centre, up, true);
    return v * m;
}

Mat4x4 Mat4x4::getMVPMatrixOGL(Vec3 pos, Vec3 rot, Vec3 scale, Vec3 eye, Vec3 centre, Vec3 up, float fovRad, float aspectRatio, float near, float far)
{
    Mat4x4 m = Mat4x4::getModelMatrix(pos, rot, scale, true);
    Mat4x4 v = Mat4x4::getViewMatrix(eye, centre, up, true);
    Mat4x4 p = Mat4x4::getProjectionMatrix(fovRad, aspectRatio, near, far, true);
    return p * v * m;
}

我看到了由此产生的矩阵的几个观察问题。当相机非常靠近模型时,它看起来相当正常,在正常情况下在y轴上旋转。然而,随着相机越来越远离模型,模型围绕y轴以圆形方式旋转,半径增加。此外,模型看起来在旋转的顶点看起来略微平坦,但这可能是由于视图矩阵的性质造成的?

这个观察是使用MV矩阵而不是投影矩阵。当我使用MVP矩阵时,事情变得更糟。该模型看起来几乎完全平坦,有些顶点与我的远剪辑一样长,通常为1000.0f。我的第一个想法是我有一些转置问题,但我知道我的转置功能正常工作。我的Mat4x4类本身是行专业,因为数学建议是正常的格式。 oglformat booleans转换为专业。我做错了什么?

0 个答案:

没有答案