2013-01-13 36 views
4

有沒有簡單的方法可以使用帶有OpenGL功能的QMatrix4x4,特別是glMultMatrixf使用帶有OpenGL功能的QMatrix4x4

如果我沒有理解這個權利,我不得不轉置矩陣,並且一定要轉換qreal(它可以是floatdouble根據底層系統)來GLfloat。 是不是有一個這樣的功能?

我也有QVector3D同樣的問題,我需要在glVertex3fv功能GLfloat陣列。

回答

4

首先我想提一下,QMatrix4x4內置了矩陣乘法運算符(第二個矩陣,一個向量或一個標量)。但是,您的問題仍然需要一個答案,因爲您希望遲早將矩陣傳遞給OpenGL。

QMatrix4x4使用qreals進行內部表示。雖然該類直接用於OpenGL(根據Bart在答案中的建議,使用constData()),但如果要保持平臺兼容性(在嵌入式中),可以確保將其傳遞給相應的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 [source:Qt5/qglobal。h]

+0

謝謝你,正是我所需要的(儘管我會更喜歡答案,Qt提供了這個) – Misch

+0

@Misch好吧,這是[QGLFunctions](http://qt-project.org/doc/qt-4.8 /qglfunctions.html)mixin,所以如果你從這個mixin繼承,你可以靜靜地使用Qt的OpenGL函數包裝器。然而,他們並不聰明地引入重載。也許有一個很好的理由 - 但我看不到它。 – leemes

2

qreal被定義爲除ARM體系結構之外的所有平臺上的雙精度值。所以他們最有可能是雙打的。

這就是說,是的,你可以使用你的QMatrix4x4完美的與OpenGL,使用constData()方法。當然,如果使用雙精度型,則要麼使用glMultMatrixd,要麼創建一個浮點矩陣。這可能不是你想要做的。 Qt在OpenGL演示中使用了矩陣類型。儘管(儘管我廣泛使用Qt),但我個人從未使用過Qt的矩陣和向量類型,但是我喜歡使用像Eigen,GLM或其他適合的庫。

+0

你確定'constData()'給我我想要的嗎?我不需要轉置矩陣來使用它的女巫OpenGL? – Misch

+0

@Misch根據代碼文檔,數據是專門佈置的,以便最適合傳遞給OpenGL函數。所以不,你不需要擔心這一點。 – Bart

+0

我在Qt文檔中找不到這個,但我認爲'constData'以行的方式返回它的數據。 (我發現的唯一的東西是這樣的:「QGenericMatrix'的構造函數中,」數組值的內容被假定爲行主要順序。「)。然而,OpenGL使用列主矩陣 – Misch