4

有没有一种简单的方法来使用QMatrix4x4OpenGL 函数,特别是glMultMatrixf

如果我理解这一点,我将不得不转置矩阵,并确保将qreal(可以是floatdouble取决于底层系统)转换为GLfloat. 没有一个功能可以为我做这件事吗?

我也有同样的问题QVector3D,我再次需要GLfloat在函数中作为数组glVertex3fv

4

2 回答 2

4

首先我想提一下,它QMatrix4x4具有用于矩阵乘法的内置运算符(带有第二个矩阵、向量或标量)。但是,您的问题仍然需要答案,因为您希望迟早将矩阵传递给 OpenGL。

QMatrix4x4用于qreals内部表示。虽然该类旨在直接与 OpenGL 一起使用(constData()如 Bart 在他的回答中所建议的那样使用),但如果您想保持平台兼容性(在嵌入式设备上),您可以确保根据类型将其传递给相应的 OpenGL 函数,qrealfloat!):

// these are defined in the OpenGL headers:
void glMultMatrixf(const GLfloat *m);
void glMultMatrixd(const GLdouble *m);

// add overloaded functions which call the underlying OpenGL function
inline void glMultMatrix(const GLfloat  *m) { glMultMatrixf(m); }
inline void glMultMatrix(const GLdouble *m) { glMultMatrixd(m); }

// add an overload for QMatrix4x4 for convenience
inline void glMultMatrix(const QMatrix4x4 &m) { glMultMatrix(m.constData()); }

您也可以将此机制用于向量,这里是glVertex*系列,由于“原始指针”重载需要考虑的组件数量,它更有意义,但面向对象的重载可以自动为您完成:

inline void glVertex2v(const GLfloat  *v) { glVertex2fv(v); }
inline void glVertex2v(const GLdouble *v) { glVertex2dv(v); }
inline void glVertex3v(const GLfloat  *v) { glVertex3fv(v); }
inline void glVertex3v(const GLdouble *v) { glVertex3dv(v); }
inline void glVertex4v(const GLfloat  *v) { glVertex4fv(v); }
inline void glVertex4v(const GLdouble *v) { glVertex4dv(v); }

// Note that QVectorND use floats, but we check this during compile time...
Q_STATIC_ASSERT(sizeof(QVector2D) == 2*sizeof(float));
Q_STATIC_ASSERT(sizeof(QVector3D) == 3*sizeof(float));
Q_STATIC_ASSERT(sizeof(QVector4D) == 4*sizeof(float));
inline void glVertex(const QVector2D &v) { glVertex2v(reinterpret_cast<const float*>(&v)); }
inline void glVertex(const QVector3D &v) { glVertex3v(reinterpret_cast<const float*>(&v)); }
inline void glVertex(const QVector4D &v) { glVertex4v(reinterpret_cast<const float*>(&v)); }

// Even for QPointF we can do it!
Q_STATIC_ASSERT(sizeof(QPointF) == 2*sizeof(qreal));
inline void glVertex(const QPointF &v) { glVertex4v(reinterpret_cast<const qreal*>(&v)); }

因此,如果进行以下更改,您的代码将保持有效:

  • Qt 将QVector*/的表示更改为QMatrix分别使用浮点数 / 双精度数,
  • 您的代码更改了向量的分量数

...而在使用原始 OpenGL 命令(如glVertex3f.

上面代码中的Q_STATIC_ASSERT离子是从 Qt 5.0 开始定义的。如果您使用的是 Qt4(或具有 Qt4 兼容性的代码),请将其添加到一些全局头文件中/在您的定义之前:http ://ideone.com/VDPUSg [来源:Qt5 / qglobal.h]

于 2013-01-14T18:19:55.873 回答
2

qreal在所有平台上都被定义为双精度,ARM 架构除外。所以对你来说,他们很可能是双打。

也就是说,是的,您可以使用该方法将 QMatrix4x4 与 OpenGL 完美结合使用constData()。当然,对于 double 类型,您要么必须使用glMultMatrixd,要么从中创建一个浮点矩阵。这可能不是您想要做的。Qt 有各种示例在他们的 OpenGL 演示中使用矩阵类型。

我个人从不在我的 OpenGL 代码中使用 Qt 的矩阵和向量类型(即使我广泛使用 Qt),而是选择像 Eigen、GLM 或其他合适的库。

于 2013-01-13T11:56:56.693 回答