I have a simple OpenGL app that displays arbitrary 3D models. I’d like to implement zoom. what I have now uses glScale, and works to some degree. However, I’m having two issues.
-
Any sort of zoom (+) quickly gets to the point where the edges of the object are inside the near clipping plane. Right now, my zNear is something like 0.1, so it makes sense that increasing the scale of the object will cause clipping. I am wondering if there are any other approaches for achieving a better effect.
-
As I zoom in, the object gets dimmer. Zoom out and it gets brighter. I have a light position at around 0, 0, 100. I have very simple lighting positioned at 0,0,100 and using only diffuse.
gl.glEnable(GL10.GL_LIGHTING); gl.glEnable(GL10.GL_LIGHT0); gl.glEnable(GL10.GL_COLOR_MATERIAL); float[] lights; lights = new float[] { 0f, 0f, 0f, 1f }; gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, lights, 0); lights = new float[] { 1f, 1f, 1f, 1f }; gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, lights, 0); lights = new float[] { 0f, 0f, 0f, 1f }; gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_SPECULAR, lights, 0); float matAmbient[] = { 0f, 0f, 0f, 1f }; float matDiffuse[] = { 1f, 1f, 1f, 1f }; float matSpecular[] = { 0f, 0f, 0f, 1f }; gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_AMBIENT, matAmbient, 0); gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_DIFFUSE, matDiffuse, 0); gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_SPECULAR, matSpecular, 0); float lightPosition[] = { mesh.mid.vertex[X], mesh.mid.vertex[Y], 100f, 1f }; gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, lightPosition, 0);
I do not have attenuation settings, which I believe needs to be enabled to cause the light to be affected by distance. Regardless, I’m not changing the distance of the object, just scaling it. Sure the position of the faces are changing but not significantly. Anyway, I’d thinking zooming in would cause it to get brighter, not dimmer.
This happens to be using opengl-es 1.0 on the Android platform.
The partial answer to #2 is that I was not scaling my normals. In other words, the previously normalized normal values have a greater (relative) magnitude when the object is scaled smaller, causing the faces to reflect more light … and vice versa.
You can set a parameter,
and it solves the problem, at the expense of some extra calculations. the full story is here,
http://www.opengl.org/resources/features/KilgardTechniques/oglpitfall/
(see #16).