2012-01-17 12 views
0

私の問題はOpenGLとノーマルに関するものです。私はそれらの背後にある数学を理解しています。OpenGL計算法(クワッド)

ここでは、インターリーブされた頂点配列を受け入れ、4つの頂点ごとに法線を計算する関数について説明します。これらは、同じ方向性を持つQUADSを表す。私の理解では、これらの4つの頂点は同じNormalを共有する必要があります。彼らが同じように直面している限り。

私が抱えている問題は、私のQUADSが対角線グラデーションでレンダリングしていることです。これは、このようなものです。Light Effect - シャドーが中央にあり、コーナーに光があります。

私はQUADSを一貫した方法で描きます。 TopLeft、TopRight、BottomRight、BottomLeft、および私の法線を計算するために使用する頂点はTopRight - TopLeftとBottomRight - TopLeftです。

誰かが私が大失敗したことを見ることができたらうれしいですが、私は何時間も勝っていませんでした。

私はキューブをレンダリングし、私の照明のチェックのためにオブジェクトの隣にあるティーポットが機能しているので、ライトの位置に関する問題はないと私は確信しています。

void CalculateNormals(point8 toCalc[], int toCalcLength) 
{ 
    GLfloat N[3], U[3], V[3];//N will be our final calculated normal, U and V will be the subjects of cross-product 
    float length; 

for (int i = 0; i < toCalcLength; i+=4) //Starting with every first corner QUAD vertice 
{ 
    U[0] = toCalc[i+1][5] - toCalc[i][5]; U[1] = toCalc[i+1][6] - toCalc[i][6]; U[2] = toCalc[i+1][7] - toCalc[i][7]; //Calculate Ux Uy Uz 
    V[0] = toCalc[i+3][5] - toCalc[i][5]; V[1] = toCalc[i+3][6] - toCalc[i][6]; V[2] = toCalc[i+3][7] - toCalc[i][7]; //Calculate Vx Vy Vz 

    N[0] = (U[1]*V[2]) - (U[2] * V[1]); 
    N[1] = (U[2]*V[0]) - (U[0] * V[2]); 
    N[2] = (U[0]*V[1]) - (U[1] * V[0]); 

    //Calculate length for normalising 
    length = (float)sqrt((pow(N[0],2)) + (pow(N[1],2)) + (pow(N[2],2))); 

    for (int a = 0; a < 3; a++) 
    { 
     N[a]/=length; 
    } 

    for (int j = 0; i < 4; i++) 
    { 
        //Apply normals to QUAD vertices (3,4,5 index position of normals in interleaved array) 
     toCalc[i+j][3] = N[0]; toCalc[i+j][4] = N[1]; toCalc[i+j][5] = N[2]; 
    } 
} 
} 
+0

これはC++です。あなたは[GLM](http://glm.g-truc.net/)のような数学ライブラリを使うことを考えましたか? –

+0

残念ながらこれは割り当てのためのものであり、ライブラリの使用をお勧めしません。 – LBHoward

答えて

2

あなたは、インデックス5からの計算で使用するための頂点位置の値を取る6、および7、その後、インデックス3で法線を書き出し、4、およびインデックス5がどのように5注意されているように思えます両方で使用されます。私はそれらの1つが正しくないと思います。

+0

ありがとう、私は顔の中で私を見つめているそれはいくつかの小さな問題だった気がしていた。締め切りは木曜日ですので、最終的な問題を解決するためノンストップで作業しています。 – LBHoward

2

あなたのfor-loopsがあなたを噛んでいるようです。

for (int i = 0; i < toCalcLength; i+=4) //Starting with every first corner QUAD vertice 
{ 
    ... 
    for (int j = 0; i < 4; i++) 
    { //   ^ ^
    // Should you be using 'j' instead of 'i' here? 
    // j will never increment 
    // This loop won't be called at all after the first time through the outer loop 
    ... 
    } 
} 
+0

まあ、これは巨大な問題に直面しています。ありがとう! – LBHoward

2

あなたは、通常の格納するためのインデックス3、4、およびを使用します。

toCalc[i+j][3] = N[0]; toCalc[i+j][4] = N[1]; toCalc[i+j][5] = N[2]; 

あなたはポイントを得るために、インデックス、6および7を使用して座標:

U[0] = toCalc[i+1][5] - toCalc[i][5]; U[1] = toCalc[i+1][6] - toCalc[i][6]; U[2] = toCalc[i+1][7] - toCalc[i][7]; 

これらのインデックスは重複しています(normal.xはposition.zと同じインデックスを共有します)。w hichは起こってはいけません。


推奨事項:

  1. 構造にすべてをかけます。
    1. 数学ライブラリを使用してください。
    2. またはベクトル演算を別々の適切な名前のサブルーチンに入れます。
  2. インデックスの代わりに名前付き変数を使用します。

これにより、コード内のバグの数を減らすことができます。 a.position.xquad[0][5]よりも読みやすく、コードがコピー貼り付けされていない場合は、ベクター操作の入力ミスを修正する方が簡単です。


あなたはインデックスと名前の両方でベクトル成分にアクセスするために労働組合を使用することができます

:クワッドABCDで、通常のcalcualtingについて

struct Vector3{ 
    union{ 
     struct{ 
      float x, y, z; 
     }; 
     float v[3]; 
    }; 
};  

A--B 
| | 
C--D 

使用式:

normal = normalize((B.pos itposition - A.position)X(C.position - A.position))。

OR

正常=ノーマライズ((D.position - A.position)X(C.position - B.position))。

ここで、「X」は「クロス積」を意味します。

いずれにしても正常に動作します。

+0

入力していただきありがとうございます。数学はすべて整っていましたが、正しく指摘すると、法線は私のVerticesと重なっていました。 – LBHoward