Light and shadow not working in opengl and c++

I am creating the solar system and I keep running into problems with the lighting. The first problem is that the moon casts no shadows on the earth and the earth casts no shadows on the moon. The other problem is that the light that is shining on the the earth and the moon are not coming from my sun, but from the center point of the orbit. I added the red lines in the picture below to show what I mean.

the picture below should illustrate what my two problems are.

在这里输入图像描述

Here is the code that is dealing with the lights and the planets.

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;

This next functions are used to determine the orbit coordinate and location of each planet

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();

}

What am I doing wrong? I read up on the w component of GL_POSITION and I changed my position to be 200 (where the sun is centered), but the light source is still coming from the center of the orbit.


To make a proper reply for the light position issue..

[X, Y, Z, W] is called homogenous coordinates

A coordinate [X, Y, Z, W] in homogenous space is will be [X/W, Y/W, Z/W] in 3D space.

Now, consider the following W values :

  • W=1.0 : [1.0, 1.0, 1.0, 1.0] is [1.0, 1.0, 1.0] in 3D place.
  • W=0.1 : [1.0, 1.0, 1.0, 0.1] is [10.0, 10.0, 10.0] in 3D place.
  • W=0.001 : [1.0, 1.0, 1.0, 0.001] is [1000.0, 1000.0, 1000.0] in 3D place.
  • When we keep moving towards W=0 the [X/W, Y/W, Z/W] values approaches a point at infinity. It's actually no longer a point, but a direction from [0,0,0] to [X,Y,Z] .

    So when defining the light position we need to make sure to get this right.

  • W=0 defines a directional light, so x,y,z is a directional vector
  • W=1 defined a positional light, so x,y,z is a position in 3D space
  • You'll get to play around with this a lot once you dig deeper into matrix math. If you try to transform a direction (W=0) with a translation matrix for example, it will not have any effect. This is very relevant here as well since the light position will be affected by the modelview matrix.

    Some easy to understand information here for further reading : http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/


    If OpenGL doesn't have a "cast shadow" function, how could I acomplish this then?

    What you must understand is, that OpenGL has no concept of a "scene". All OpenGL does is drawing points, lines or triangles to the screen, one at a time. After it's drawn, it has no influence on the following drawing operations.

    So to do something fancy like shadows, you must get, well, artistic. By that I mean, like an artist who paints a plastic picture which has depth with "just" a brush and a palette of colours, you must use OpenGL in a artistic way to recreate with it the effects you desire. Drawing a shadow can be done in various ways. But the most popular one is known by the term Shadow Mapping.

    Shadow Mapping is a two step process. In the first step the scene is rendered into a "grayscale" picture "seen" from the points of view of the light, where the distance from the light is drawn as the "gray" value. This is called a Shadow Depth Map.

    In the second step the scene is drawn as usual, where the lights' shadow depth map(s) are projected into the scene, as if the lights were a slide projector (where everything receives that image, as OpenGL doesn't shadow). In a shader the depth value in the shadow depth map is compared with the actual distance to the light source for each processed fragments; if the distance to the light is farther than the corresponding pixel in the shadow map this means that while rendering the shadow map something got in front of the currently processed geometry fragment, which hence lies in the shadow, so it's drawn in a shadow color (usually the ambient illumination color); you might want to combine this with an Ambient Occlusion effect to simulate soft, self shadowing ambient illumination.

    链接地址: http://www.djcxy.com/p/78208.html

    上一篇: 原子数据类型在C#原子(线程安全)?

    下一篇: 光影不在opengl和c ++中工作