移植 OpenGL 矩阵运算以提升 QVM

Posted

技术标签:

【中文标题】移植 OpenGL 矩阵运算以提升 QVM【英文标题】:Port OpenGL Matrix Operations to Boost QVM 【发布时间】:2016-12-07 14:06:51 【问题描述】:

我的应用程序中有一些遗留代码正在使用 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> v0.0, -speed, 0.0;
boost::qvm::mat<double, 4, 4> translation = boost::qvm::translation_mat(v);

【问题讨论】:

是否需要 boost::qvm?你考虑过glm library吗? Boost 只是一个要求,因此我们不必添加另一个外部依赖项。我不知道 glm,但由于它似乎只是标题,它可能是一种可能性。同时,我想看看这里的 qvm 解决方案是否合理。 【参考方案1】:

Rotationtranslation 矩阵可以使用 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&lt;double, 4, 4&gt; matrix;行声明的矩阵)。

【讨论】:

【参考方案2】:

最好不要将来自view proxies 的中间结果(如translation_matroty_mat)放入mat&lt;&gt; 对象中。要么在auto const &amp; 中捕获中间结果,要么直接将它们相乘,如下所示。这样可以避免创建任何临时对象。

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);

【讨论】:

以上是关于移植 OpenGL 矩阵运算以提升 QVM的主要内容,如果未能解决你的问题,请参考以下文章

基于OpenMP的矩阵乘法实现及效率提升分析

openGL 坐标系的互相转换

在有限内存上对大型矩阵进行矩阵运算

如何仅使用矩阵运算创建这个精确的 5x5 矩阵?

Jupyter中的Python矩阵基本运算的学习记录

矩阵及矩阵运算