Edit: Sorted some things out but now I have strange lighting effect where only one planet is properly lit (light on one side dark on the other) and the rest are fully lit. Odd.
I have a fairly large solar system simulator project (done in Qt for UI) but I can’t quite get texture and lighting to work and I think it’s mainly because my class structure has become a bit of a mess and I’m not sure what’s happening when. I’m sure I’ll get stick for my class structure but this is just the way it’s worked out.
Here’s the simple class breakdown.
There’s a SpaceObject base class which has derived classes of Planets, Stars, etc…
There’s a SpaceSystem class in which the solar system and all integrators and textures are initialized.
There’s an OpenGL class (derived from QGLWidget - a Qt OpenGL class).
Each SpaceObject has its own draw function which is declared as virtual in the SpaceObject class as certain objects (stars, satellites) will require different rendering instructions.
SpaceSystem has a draw function which draws the skybox background, a faint grid, position markers for the objects and calls the draw function for each SpaceObject.
OpenGL has a paint function (as all QGLWidgets do) which sets up two perspective calls so that far objects and near objects can be rendered without having a tiny zNear and huge zFar (using actual solar system scales). It then calls the SpaceSystem draw function.
I’ve become quite confused as to whether certain material and light calls are still active at any time and I’m not sure when all these need to actually be called and how often! I should say that I’m a maths guy and this is more of a maths exercise than anything and I don’t really like graphics programming which is why there will likely be a lot of mistakes in the codes below…
The paint function in the OpenGL class
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
yaw += 4.0*yawTemp;
pitch += 4.0*pitchTemp;
if (yaw >= 360.0f) { yaw -= 360.0f; }
else if (yaw < 0.0f) { yaw += 360.0f; }
if (pitch >= 360.0f) { pitch -= 360.0f; }
else if (pitch < 0.0f) { pitch += 360.0f; }
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (GLfloat)width/(GLfloat)height, 0.1f, 120.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(5.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,-1.0);
solarSystem->draw(yaw, pitch, xMove, yMove, zMove, markersOn);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (GLfloat)width/(GLfloat)height, 0.0001f, 0.1f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(5.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,-1.0);
solarSystem->draw(yaw, pitch, xMove, yMove, zMove);
The draw function in SpaceSystem
glEnable(GL_TEXTURE_2D);
glEnable(GL_LIGHTING);
glDisable(GL_DEPTH_TEST);
drawBackground(yaw, pitch);
glDisable(GL_TEXTURE_2D);
glDisable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
if (drawMarkers)
{
drawPositionMarkers(yaw, pitch, xMove, yMove, zMove);
}
drawGrid(yaw, pitch, xMove, yMove, zMove);
glEnable(GL_TEXTURE_2D);
drawObjects(yaw, pitch, xMove, yMove, zMove);
The drawObjects function calls the draw functions in all the SpaceObjects and also binds textures.
The draw function in the SpaceObject class uses the icosahedron algo to draw spheres, deals with whether it is actually visible and draws an orbital trail.
I have a feeling this whole thing needs a total overhaul and has just become function programming inside classes as it’s starting to look awful from an outside perspective.
What I’d like to know is, where do I put the light call and the material calls? The light call is currently inside the drawObjects function which draws the sun with lighting off then turns it on to draw everything else using the suns position. The material calls are inside the SpaceObjects class which has a setUpGL function which sets up material properties for each object type (e.g. sun will of course be difference from planets and moons). It gets called when the SpaceObject is initialized and it is…
float mColour[] = {R, G, Blue, 1.0f};
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mColour);
GLfloat mat_specular[] = {0.3f, 0.3f, 0.3f, 1.0};
GLfloat mat_shininess[] = { 40.0 };
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
Since I am disabling and enabling light and texture calls for different draw commands, do I need to recall all the material and light functions? I have a feeling I’ll get a link to a beginner guide with how to do this basic stuff but really that won’t help because I’ve never found a guide yet that deals with this sort of thing on individual class objects which all have slightly different properties. It’s always drawing a single textured object with lighting in the one class. I can do this no bother but all this classes stuff has made it hellishly confusing.
(FYI the rest of the classes, integrator, UI etc, are all set up nicely, I’ve just always found it difficult to set up classes when dealing with graphics)