2012-02-28 4 views
2

私はエンジンを書いていて、シーンの「太陽」としてライト0を使用しています。太陽は指向性の光です。OpenGL指向照明+ポジショニング

シーンの直交視点を設定し、画面の「東」側(および文字)に光を設定します(x/yは平面の地形の座標で、正のzをカメラに向けます)。地形上に「高さ」を示す - シーンもx軸の等角図に対して回転します)。

光が0,0,0の明るい「東」を照らしているように見えますが、文字が動くとシフトしません(CenterCameraは指定された値の負の値でglTranslate3fを実行します。世界座標)。意味は、さらに私は西に移動する、それは常に暗い、光なしです。

Graphics.BeginRenderingLayer(); 
    { 
     Video.MapRenderingMode(); 

     Graphics.BeginLightingLayer(Graphics.AmbientR, Graphics.AmbientG, Graphics.AmbientB, Graphics.DiffuseR, Graphics.DiffuseG, Graphics.DiffuseB, pCenter.X, pCenter.Y, pCenter.Z); 
     { 
      Graphics.BeginRenderingLayer(); 
      { 
       Graphics.CenterCamera(pCenter.X, pCenter.Y, pCenter.Z); 
       RenderMap(pWorld, pCenter, pCoordinate); 
      } 
      Graphics.EndRenderingLayer(); 

      Graphics.BeginRenderingLayer(); 
      { 
       Graphics.DrawMan(pCenter); 
      } 
      Graphics.EndRenderingLayer(); 
     } 
     Graphics.EndLightingLayer(); 
    } 
    Graphics.EndRenderingLayer(); 

Graphics.BeginRenderingLayer = PushMatrix、EndRenderingLayer = PopMatrix Video.MapRenderingMode =オルソ投影シーン回転/ズームCenterCamera文字が今でセンタリングされるように、X/Y/Zの反対側に変換ありませんX/Y/Zを画面中央に表示します。

どのような考えですか?多分私のコードのいくつかをここで少し混乱させてしまったでしょうか?次のように

照明コードは次のとおりです。

public static void BeginLightingLayer(float pAmbientRed, float pAmbientGreen, float pAmbientBlue, float pDiffuseRed, float pDiffuseGreen, float pDiffuseBlue, float pX, float pY, float pZ) 
    { 
     Gl.glEnable(Gl.GL_LIGHTING); 
     Gl.glEnable(Gl.GL_NORMALIZE); 
     Gl.glEnable(Gl.GL_RESCALE_NORMAL); 
     Gl.glEnable(Gl.GL_LIGHT0); 

     Gl.glShadeModel(Gl.GL_SMOOTH); 

     float[] AmbientLight = new float[4] { pAmbientRed, pAmbientGreen, pAmbientBlue, 1.0f }; 
     float[] DiffuseLight = new float[4] { pDiffuseRed, pDiffuseGreen, pDiffuseBlue, 1.0f }; 
     float[] PositionLight = new float[4] { pX + 10.0f, pY, 0, 0.0f }; 
     //Light position of Direction is 5 to the east of the player. 

     Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_AMBIENT, AmbientLight); 
     Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_DIFFUSE, DiffuseLight); 
     Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_POSITION, PositionLight); 

     Gl.glEnable(Gl.GL_COLOR_MATERIAL); 
     Gl.glColorMaterial(Gl.GL_FRONT_AND_BACK, Gl.GL_AMBIENT_AND_DIFFUSE); 
    } 
+1

ライトを設定する場所を示すコードを投稿すると役立ちます。 – kappamaki

+0

照明コードを含むようにオリジナルを編集しました。 – Locke

+0

各頂点の法線を計算して送信していますか? –

答えて

3

あなたはそれぞれの表面のための法線を提供する必要があります。何が起こっているのか(法線なし)は、指向性の光が本質的に0の東側に位置的に輝いているのに対し、そこにあるものはすべて0,0,1のノーマル(西に面しています)です。

送信する必要はありませんノーマルは各頂点について私が知る限りではなく、GLがステートマシンであるため、通常の変更を行うたびに変更する必要があります。キューブの面をレンダリングしているのであれば、「西の顔は、X-Y-Z整列直角プリズム、「整数」の場合は、単一のコール

glNormal3i(0,0,1); 
glTexCoord.. 
glVertex3f... 
glTexCoord.. 
etc. 

を持つべきであるのに十分です。 6つの主要な方向の1つに直面しない顔の場合は、それらを正規化する必要があります。私の経験では、クワッドがフラットでない限り、最初の3つのポイントを正規化する必要があります。これは、クワッド内の最初の3辺によって形成された三角形の法線を見つけることによって行われます。

私は啓蒙を見つけた「法則を計算する」にいくつか簡単な言葉があります。

これの第2の部分は指向性のライトであるため、プレーヤーの位置でそれを再配置することは意味をなさない(W = 0)。あなたは、常にフロントライトになりたいという光自体はカメラの後ろから放出されているとあなたが(モデルのような)の前にオブジェクトを回転している場合を除き、その位置は、おそらく

float[] PositionLight = new float[4] { 0.0f, 0.0f, 1.0f, 0.0f }; 

のようなものでなければなりませんGLX方向(すなわち、あなたが最初に北/南に直面している)東西方向として解釈されている場合や、

float[] PositionLight = new float[4] { 1.0f, 0.0f, 0.0f, 0.0f }; 

コンセプトは、あなたがあたり、顔の光を計算し、そして光はdoesnの場合されていることですシーン自体が動いていない(ちょうどシーンの周りを動くカメラ)方向計算は常に正しいままです。法線が正確であれば、GLは特定の顔に現れる光の強さを把握することができます。

最後に、GLは自動的にシャドウを処理しないということです。基本的なGL_Lightは、一連の凸形状の制御された照明には十分であるため、光(太陽など)を顔に適用する必要があるかどうかを判断する必要があります。場合によっては、これは、顔が属するソリッドを取って、太陽の光のベクトルが「空」に達する前に別のソリッドと交差するかどうかを調べることです。

これについては、ライトマップやシャドウマップのものを探してください。

2

多くの人を飛び越えることができることの1つは、glLightFvに送信されたポジションが現在のマトリックススタックによって翻訳されていることです。したがって、ライトをワールド座標系の特定の位置に設定したい場合は、glLightFv呼び出しの際に、カメラと投影行列をマトリックススタック上に設定してアクティブにする必要があります。

関連する問題