2011-12-06 2 views
0

最近、データ型のユニオン記憶域指定子について学びました。特にOpenGL/DirectX変換行列用です。廃止されたgluLookAt、gluOrtho、および固定機能パイプラインのさまざまなMatrixStack機能素晴らしいことですが、私は最近、Matrix内のデータにアクセスするさまざまな方法を可能にするために、内部データが組み合わされた4x4の基本変換マトリックスクラスを作成することが大いに面白かったです。私はいくつかの奇妙な「列メジャー」形式のクラス/ユニオンデータへのアクセスC++

float* Column(int index); 

機能を加えることなく、その列でデータにアクセス/集約の方法を作成するときに問題があります。私はC++がデータを行優先形式で格納することを知っています。したがって、列アクセスをどのように提供するのですか?そこに???私が失っている場所に関する私の下の行列データ宣言で。

//#define ROW_EFFIN_MAJOR 
union { 
    struct { 
#ifdef ROW_EFFIN_MAJOR 
// Eat one of several nasty things, OpenGL :| 
     float m11, m12, m13, m14, 
       m21, m22, m23, m24, 
       m31, m32, m33, m34, 
       m41, m42, m43, m44; 
#else 
     float m11, m21, m31, m41, 
       m12, m22, m32, m42, 
       m13, m23, m33, m43, 
       m14, m24, m34, m44; 
#endif 
    }; 
    float m[16]; 
    // Use at your own risk: m[1] COLUMNMAJOR is not the same as m[1] ROWMAJOR 
    // Rows! 
    union MatrixRow { 
     struct { 
      float r1, r2, r3, r4; 
     }; 
     float r[4]; 
    } row[4]; 
    // .... Columns...? 
    union MatrixColumn { 
     // TODO: 
     // Set Union 
     // Column Access ? 
     // ??? 
     // Profit 
    } col[???]; 
}; 

アドバイス、ヒント、トリック、または助けてもいいですね。理想的には、私はcol [0] .c1、または単にcol [0] .c(cは全体の列のfloat [4]である)によって列にアクセスしたいと思います。しかし、この理想が、カラムアクセスの正義のために殺されるのであれば(ただし、関数ではなく、特殊な構造体と関数で行うことができるため、アクセスするよりも少し不便ですそのデータはデータメンバーを介して直接的に)。

私はgoogle-fuでこれをバッシュしようとかなりの時間を費やしましたが、非連続的な結合を作る方法を理解できません。

+1

C++には、多次元配列の概念がないため、大きな次元の概念はありません。配列の配列の概念をサポートしていますが、内部配列の列または行を呼び出すかどうかは、主にあなた次第です。それらを行として参照する方が一般的です。なぜなら、それらは初期化するときにソースコードの行に対応するからですが、それは純粋に偶発的なことです。 –

+1

Aaah union abuse! –

+0

@WTP連合虐待、そうですか? MatrixRowユニオンを使用して独自のデバッガビジュアライザを作成するだけでなく、ポインタジャンプを開始することなく4つのシーケンシャルデータ要素にアクセスしてグループ化することができます。私が自分の 'Union4 Vector4 'を完成させたら、もっと楽しくなるでしょう。 :D – Andhera

答えて

2

Marceloから指摘されているように、C++は行優先でも列主優先でもありません。それはあなたがそれに入れたものだけです。 float配列の最初の4つの値を "列"と呼ぶと、それは問題ありません。あなたはそれを「行」と呼んでも、それも問題ありません。

一般に、慣習間で切り替えるべきではありません。 "両方"を行うことができる構造体を開発しないでください。ちょうど側面を選択し、それに固執する。マトリックスを行メジャーにすると、行メジャーになります。 OpenGLにアップロードするときは、手動でトランスポーズするか、glUniformMatrixの "transpose"パラメータにGL_TRUEを渡すだけです。

詳細are available

+0

まあ、お返事ありがとうございます。私は、「スキップ4フロート」の方法でデータを張ることができないことを知っていましたが、私が推測していることを確認するだけの価値がありました。私はあなたの答えを今のところ答えにするつもりですが、いつか私が周りを回ることができることを心から願っています。 – Andhera

+0

しかし、素早い副問:glUniformMatrixに当てはまるわけではありませんが、あなたが渡すすべての単一のマトリックスについては、少し遅くなります。なぜなら、OpenGLはあなたのマトリックスを毎回転置しなければならないからです。つまり、行列を転置するのは技術的にSWAPコマンドの6つだけですが... – Andhera

関連する問題