TRo*_*Rod 1 c++ opengl lighting
我正在创建太阳系,但我不断遇到照明问题。第一个问题是月球没有在地球上投射阴影,地球也没有在月球上投射阴影。另一个问题是,照在地球和月球上的光不是来自我的太阳,而是来自轨道的中心点。我在下图中添加了红线来表达我的意思。
下图应该说明我的两个问题是什么。

这是处理灯光和行星的代码。
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;
Run Code Online (Sandbox Code Playgroud)
接下来的函数用于确定每个行星的轨道坐标和位置
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();
}
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?我阅读了 GL_POSITION 的 w 分量,并将位置更改为 200(太阳位于中心的位置),但光源仍然来自轨道中心。
针对灯光位置问题做出正确的答复..
[X, Y, Z, W]称为齐次坐标
齐次空间中的坐标[X, Y, Z, W]将是[X/W, Y/W, Z/W]3D 空间中。
现在,考虑以下 W 值:
W=1.0:[1.0, 1.0, 1.0, 1.0]处于[1.0, 1.0, 1.0]3D 位置。W=0.1:[1.0, 1.0, 1.0, 0.1]处于[10.0, 10.0, 10.0]3D 位置。W=0.001:[1.0, 1.0, 1.0, 0.001]处于[1000.0, 1000.0, 1000.0]3D 位置。当我们不断朝着价值观前进时,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/