1

私は太陽系を作成していますが、照明に問題が発生し続けています。最初の問題は、月が地球に影を落とさず、地球が月に影を落とさないことです。他の問題は、地球と月を照らしている光が私の太陽からではなく、軌道の中心点から来ていることです. 私が何を意味するかを示すために、下の図に赤い線を追加しました。

下の図は、私の 2 つの問題が何であるかを示しているはずです。

ここに画像の説明を入力

ライトと惑星を扱うコードは次のとおりです。

glDisable(GL_LIGHTING);
    drawCircle(800, 720, 1, 50);
    //SUN
                //Picture location, major radius, minor radius, major orbit, minor orbit, angle
    Planet Sun ("/home/rodrtu/Desktop/SolarSystem/images/Sun.png", 
                     100, 99, 200.0, 0.0, 0.0);
    double sunOrbS = 0;
    double sunRotS = rotatSpeed/10;
    cout << sunRotS << " Sun Rotation" << endl;

    //orbit speed, rotation speed, moon reference coordinates (Parent planet's major and minor Axis)
    Sun.displayPlanet(sunOrbS, sunRotS, 0.0, 0.0);

    //Orbit path
    //EARTH


    GLfloat light_diffuse[] = { 1.5, 1.5, 1.5, 1.5 };
    GLfloat pos[] = { 0.0, 0.0, 0.0, 200.0 };
    glEnable(GL_LIGHTING);  
    glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
    glLightfv(GL_LIGHT0, GL_POSITION, pos);

    Planet Earth ("/home/rodrtu/Desktop/SolarSystem/images/EarthTopography.png", 
               50, 49, 500.0, 450.0, 23.5);
    double eaOrbS = orbitSpeed;
double eaRotS = rotatSpeed*3;

    Earth.displayPlanet(eaOrbS, eaRotS, 0.0, 0.0);


    //EARTH'S MOON
    Planet Moon ("/home/rodrtu/Desktop/SolarSystem/images/moonTest.png", 
               25, 23, 100.0, 100.0, 15);
    double moOrbS = rotatSpeed*4;
    double moRotS = eaOrbS;

    Moon.displayPlanet(moOrbS, moRotS, Earth.getMajorAxis(), Earth.getMinorAxis());


    orbitSpeed+=.9;
    if (orbitSpeed > 359.0)
    orbitSpeed = 0.0;


    rotatSpeed+=2.0;
    if (rotatSpeed > 7190.0)
    rotatSpeed = 0.0;

この次の関数は、各惑星の軌道座標と位置を決定するために使用されます

void Planet::setOrbit(double orbitSpeed, double rotationSpeed, 
              double moonOrbitX, double moonOrbitY) 
{
    majorAxis = orbitSemiMajor * cos(orbitSpeed / 180.0 * Math::Constants<double>::pi);
    minorAxis = orbitSemiMinor * sin(orbitSpeed / 180.0 * Math::Constants<double>::pi);

    glTranslate(majorAxis+moonOrbitX, minorAxis+moonOrbitY, 0.0);
    glRotatef(orbitAngle, 0.0, 1.0, 1.0);
    glRotatef(rotationSpeed, 0.0, 0.0, 1.0);

}

void Planet::displayPlanet(double orbitSpeed,double rotationSpeed, 
               double moonOrbitX, double moonOrbitY)
{
    GLuint surf;
    Images::RGBImage surfaceImage;
    surfaceImage=Images::readImageFile(texture);
    glEnable(GL_TEXTURE_2D);
    glGenTextures(0, &surf);
    glBindTexture(GL_TEXTURE_2D, surf);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    surfaceImage.glTexImage2D(GL_TEXTURE_2D,0,GL_RGB);

    glPushMatrix();
    setOrbit(orbitSpeed,rotationSpeed, moonOrbitX, moonOrbitY);
    drawSolidPlanet(equatRadius, polarRadius, 1, 40, 40); 
    glPopMatrix();

}

私は何を間違っていますか?GL_POSITION の w コンポーネントを読み、位置を 200 (太陽が中心) に変更しましたが、光源はまだ軌道の中心から来ています。

4

2 に答える 2

3

ライトの位置の問題について適切な回答をするために..

[X, Y, Z, W]同次座標と呼ばれる

[X, Y, Z, W]同次空間の座標は[X/W, Y/W, Z/W]3D 空間になります。

ここで、次の W 値を検討してください。

  • W=1.0: 3D の場所に[1.0, 1.0, 1.0, 1.0]あります。[1.0, 1.0, 1.0]
  • W=0.1: 3D の場所に[1.0, 1.0, 1.0, 0.1]あります。[10.0, 10.0, 10.0]
  • W=0.001: 3D の場所に[1.0, 1.0, 1.0, 0.001]あります。[1000.0, 1000.0, 1000.0]

値に向かって移動し続けるW=0[X/W, Y/W, Z/W]、無限の点に近づきます。それは実際にはポイントではなく、 から[0,0,0]への方向[X,Y,Z]です。

そのため、ライトの位置を定義するときは、これを正しく行う必要があります。

  • W=0はディレクショナル ライトを定義するため、x、y、z はディレクショナル ベクトルです。
  • W=1位置ライトを定義したため、x、y、z は 3D 空間内の位置です

行列の計算を深く掘り下げると、これをいろいろいじることができるようになります。たとえば、平行移動行列を使用して方向を変換しよう(W=0)としても、何の効果もありません。これは、ライトの位置がモデル ビュー マトリックスの影響を受けるため、ここでも非常に重要です。

さらに読むための理解しやすい情報: http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/

于 2013-05-24T22:55:37.227 に答える