I have this high-quality mesh I want to render. I just want it to appear on screen, lighted properly, without looking terrible. However, these are the current results. You can see the triangles are really highlighted, and it looks ugly. It looks worse with coarser meshes, too. I’ve checked, and my normals are being computed correctly and are all pointing out of the surface. I know that the proper way to get true Phong shading is to code a shader on the GPU, but… surely I should be able to get better results using OpenGL shading.
Additionally, I want to be able to rotate the model, but keep the light fixed. That is, I want to be able to rotate to the back half of that model, or the underside, and not see darkness. I want the light to be in the same location, regardless of how the model is rotated, so I can rotate the model and see all the areas illuminated. I’ve coded what I think to be the way it works, but clearly things aren’t going the way I think they should. I’ve read up on the lighting chapter in the openGL book, too, and I’ve tried all sorts of variations on the order of commands, but nothing seems to work. I feel like I’m not initializing something properly.
Can someone tell me where I’m going wrong with this C# code? I clearly am missing some rudimentary knowledge here. (I apologize in advance for poor tabbing in the code)
private void initGL()
{
// Set GL states, create lights, etc.
Gl.glClearColor(1.0f, 1.0f, 1.0f, 0.0f); // Let OpenGL clear to white
Gl.glShadeModel(Gl.GL_SMOOTH);
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);
Gl.glEnable(Gl.GL_DEPTH_TEST);
Gl.glEnable(Gl.GL_LIGHTING);
Gl.glEnable(Gl.GL_LIGHT0);
Gl.glEnable(Gl.GL_BLEND);
Gl.glColorMaterial(Gl.GL_FRONT_AND_BACK, Gl.GL_AMBIENT_AND_DIFFUSE);
Gl.glEnable(Gl.GL_COLOR_MATERIAL);
resizeGL(this, null);
}
private void resizeGL(object sender, EventArgs e)
{
// Set up a projection
int w = glControl.Size.Width, h = glControl.Size.Height;
Gl.glViewport(0, 0, w, h);
Gl.glMatrixMode(Gl.GL_PROJECTION);
Gl.glLoadIdentity();
Glu.gluPerspective(45, (double)w / (double)h, 1, 100);
// Return to modelview mode for rendering
Gl.glMatrixMode(Gl.GL_MODELVIEW);
//Gl.glLoadIdentity();
}
private void paintGL()
{
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);
Gl.glMatrixMode(Gl.GL_MODELVIEW);
Gl.glLoadIdentity();
Glu.gluLookAt(0, 0, 7, 0, 0, 0, 0, 1, 0);
Gl.glMultMatrixf(trackball.Matrix); // do rotation as per trackball
Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_POSITION, lightPosition1); // lightPosition1 is { 10, 0, 10, 0 }
Gl.glEnable(Gl.GL_LIGHTING);
surface.render();
}
// the surface.render function
private void render()
{
// some stuff
float[] spec = { 1, 1, 1, 1 };
Gl.glEnable(Gl.GL_LIGHTING);
Gl.glColor4fv(m_shadeColor);
Gl.glMaterialf(Gl.GL_FRONT_AND_BACK, Gl.GL_SHININESS, 30.0f);
Gl.glMaterialfv(Gl.GL_FRONT_AND_BACK, Gl.GL_SPECULAR, spec);
Gl.glMaterialfv(Gl.GL_FRONT_AND_BACK, Gl.GL_EMISSION, new float[] { 0, 0, 0, 1 });
Gl.glPolygonMode(Gl.GL_FRONT_AND_BACK, Gl.GL_FILL);
Gl.glShadeModel(Gl.GL_SMOOTH);
Gl.glLineWidth(2);
// surface is then rendered using VBOs
}
Changing the order of rotation and specifying the light’s position doesn’t have the effect I think it should; the light seems to rotate around properly, but rotating vertically to see the underside of the surface is still completely unlit (and I do specify GL_FRONT_AND_BACK in all my surface stuff).
I feel silly for having this problem, and even sillier asking for help on it, but … that’s what the beginner’s forum is for, right?