端口OpenGL矩阵操作以提升QVM

时间:2016-12-07 14:06:51

标签: c++ opengl matrix boost

我的应用程序中有一些遗留代码,它们使用OpenGL进行快速矩阵数学运算。看起来这可能会被boost :: qvm取代,但是使用的例子很少。基本代码是:

#include <boost/qvm/mat.hpp>
#include <boost/qvm/mat_operations.hpp>

void foo()
{
    auto heading = 90.0;
    auto speed = 10.0;
    auto xComponent = 0.0f;
    auto yComponent = 0.0f;

    glPushMatrix();
    {
        glLoadIdentity();

        glRotatef(static_cast<GLfloat>(heading), 0, 1, 0);
        glTranslatef(0, static_cast<GLfloat>(-speed), 0);

        float modelviewMatrix[16];
        glGetFloatv(GL_MODELVIEW_MATRIX, modelviewMatrix);

        xComponent = modelviewMatrix[2*4 + 0];
        yComponent = modelviewMatrix[0];
    }
    glPopMatrix();
}

所以我想知道是否有人有任何快速的想法分享如何用boost :: qvm实现这个?

因此,boost :: qvm版本应该是非常相似的,但我不知道如何进行旋转和转换,因为API与OpenGL完全不同。

void foo() 
{ 
    auto heading = 90.0;
    auto speed = 10.0;
    auto xComponent = 0.0f;
    auto yComponent = 0.0f;

    boost::qvm::mat<double, 4, 4> matrix;
    boost::qvm::set_identity(matrix);

    // rotate?

    // translate?

    // get components?
}

最终代码:

在这个问题之后,代码看起来像这样:

#include <boost/qvm/mat.hpp>
#include <boost/qvm/vec.hpp>
#include <boost/qvm/mat_operations.hpp>
#include <boost/qvm/map_vec_mat.hpp>

// ...

boost::qvm::mat<double, 4, 4> matrix;
boost::qvm::set_identity(matrix);
boost::qvm::mat<double, 4, 4> rotation = boost::qvm::roty_mat<4>(deg2rad(heading)); 
boost::qvm::vec<double, 3> v{{0.0, -speed, 0.0}};
boost::qvm::mat<double, 4, 4> translation = boost::qvm::translation_mat(v);

2 个答案:

答案 0 :(得分:1)

使用boost(示例)可以获得

旋转翻译矩阵:

boost::qvm::rotx_mat<4>(3.14159f); // rotation on x axis by PI radians

vec<float,3> v={0,0,7};
mat<float,4,4> tr=translation_mat(v); // translation by 7 units on z axis

您可以通过将模型视图矩阵与这些矩阵相乘来获得组合变换

然后,获取组件是从模型视图矩阵中读取所需值的问题(您的模型视图可以是您已使用行boost::qvm::mat<double, 4, 4> matrix;声明的矩阵)。

答案 1 :(得分:1)

最好不要将view proxies的中间结果(例如translation_matroty_mat)放入mat<>对象中。要么在auto const &中捕获中间结果,要么只是在线乘以它们,如下所示。这可以避免创造任何临时工。

auto heading = 90.0;
auto speed = 10.0;
auto xComponent = 0.0f;
auto yComponent = 0.0f;
{
    using namespace boost::qvm;
    double const v[3] = {0,-speed,0};
    auto const & result = translation_mat(vref(v)) * roty_mat<4>(deg2rad(heading));
    xComponent = A02(result); //Not sure if this should be A20 instead
    yComponent = A00(result);
}