[solved] Problem about ofLight inside an object

Hello,

I’ve already described my problem on the IRC, but since we couldn’t find the answer, I decide to post on the forum, as I think it will get more responses but also be more useful for future users.

So briefly, I just got started a few days ago with openFrameworks and I want to do OpenGL 3D with it, so I began to make a basic solar system as a kind of training exercise. My planets are all ofSpherePrimitive on which I put a texture with ofImage.

My main problem comes when we have to make the Sun a light source. I tried two things to do it:

  1. Put an ofLight point light object at the center of the sun’s ofSpherePrimitive (inside it)
  2. Use an ofMaterial with emissiveColor set to use on the Sun to make it emitting light

But in both cases I encounter strange problems:

  • with an ofLight inside the Sun, the planets around are correctly lit, but the Sun itself stays dark. screenshot
  • by using a material with emissive color on the Sun, the scene gets entirely lit, just like there was a white ambient light. But there isn’t ! screenshot

The first screenshot may not show it very well, but I think there’s also a problem with the ofLight solution since the planets don’t seem to shadow one another. There is shadow on the planets’ faces that aren’t in front of the sun, but when a planet masks a smaller one, like when they’re aligned, the one behind shouldn’t be lit at all (the sun’s light doesn’t reach it). But here, they are all lit, and I don’t understand why either.

Since I know that OpenGL lighting can be very tricky sometimes, I guess the problem lies within my draw() function, but I don’t know why. Here it is. For the reference, astres is an array of ofSpherePrimitives (sun and planets) and textures an array of ofImage.

void testApp::draw()
{
cam.begin();
// drawing orbits
// start at MERCURY because no orbit for the SUN
for (int astre = MERCURY; astre <= NEPTUNE && bDrawOrbits; astre ++)
{
    ofPushMatrix();
    ofRotateX(-90);
    ofSetColor(222, 222, 222);
    ofNoFill();
    ofSetCircleResolution(100);
    ofCircle(0, 0, astralInfos[astre].second[0]);
    ofPopMatrix();
}

// drawing planets and Sun and make them rotate
ofEnableLighting();
pointLight.enable();
for (int astre = SUN; astre <= NEPTUNE; astre ++)
{
    ofPushMatrix();
    textures[astre].getTextureReference().bind();
    astres[astre].mapTexCoordsFromTexture( textures[astre].getTextureReference() );
    if (astre == SUN)
    {
        material.begin();
        astres[astre].rotate(0.01, 0.0, 0.1, 0);
    }
    else
    {
        astres[astre].rotate(0.1, 0.0, 0.1, 0); // rotate on itself
        glRotatef(days[astre], 0.0, 1.0, 0.0); // orbit around the Sun
    }
    astres[astre].draw();
    if (astre == SUN)
    {
        material.end();
    }
    textures[astre].getTextureReference().unbind();
    ofPopMatrix();
}
ofDisableLighting();
cam.end();
}

The only operation made on the material is material.setEmissiveColor( ofFloatColor(1.0, 1.0, 1.0) ); in the setup. Here both the light and the material are used.

So if anyone has an idea on what’s the problem, any help is welcome ! :smile:

Some news here.

I’m not sure why, but it now seems clear that at least a part of my lighting problems are due to the fact that I’m using an easy cam. I know it tends to screw up the lights of a scene, and when I put

ofEnableLighting();
pointLight.enable();

before the

cam.begin();

,
at max dezoom, the sun is actually lit, and the more I zoom on it, the more it darkens.
[screenshot][1]

So I’m nearly sure the problem comes with from the ofEasyCam. I’m going to try to do it with a normal ofCamera.

Thank you for any suggestion you may have about this problem ^_^;

PS : tried with an ofCamera. exactly the same problem. Also tried without camera at all, and the sun always stays dark. Now I really don’t know what to do… :’(
[1]: http://uppix.net/m5ZnM5.png

What I feel when I look at the picture of your second way is; that you make all materials of all objects emissive, but maybe only the sun’s material should be so.

Hello,

yes, that’s my feeling too, yet I’m not sure why, because since I call material.begin() and material.end() only when I draw the sun, I can’t really understand why should it affect other planets too.

Anyway, I have some good news about this ! It seems that when something has a material on a scene, everything else better have one too.

In addition to the sun’s material with emissive color, I just tried to use another material to use for all the others planets, this one with only a specular color of (0,0,0) — black.

And it worked ! The Sun is now bright, and all the planets are correctly shaded, not illuminated like with an ambient light. My issue is solved :blush:

Now I’ve got to deal with the fact that planets don’t get shaded by a bigger one which is between them and the sun. But I’ve read somewhere that it’s normal since OpenGL doesn’t do it for you, got to do it yourself. And that’s another story. :smile:

Cheers !