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:
- Put an ofLight point light object at the center of the sun’s ofSpherePrimitive (inside it)
- 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 !