How to fix light position with rotating cube

This is the section of the code:

gl.glEnable(GL10.GL_LIGHTING);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

gl.glLoadIdentity();
gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, lightPositionBuffer);

gl.glTranslatef(0.0f, -1.2f, -10);And Into The Screen 6.0
gl.glRotatef(xrot, 1.0f, 0.0f, 0.0f);
gl.glRotatef(yrot, 0.0f, 1.0f, 0.0f);

model.draw(gl); // Draw the cube

With the above code, the surface shade continuously changes as the cube is being rotated but not the way I was expecting. As an example, the top surface continuously change the color from completel black to complete white gradually as the cube rotates on the y-axis.

If I move glLightfv() to just before draw(), then as expected, the surface doesn’t change at all during rotation since the light position receives the same transformation as the scene itself.

What am I doing wrong?

If you intend to keep the illumination of the cube constant (and I expect you do) then moving glLightfv() after the calls which (in this case) set up the view matrix (glTranslate() etc.) is correct.

The explanation for the variable illumination in you first scenario is simple: you’re not transforming the light source position at all since right before invoking glLightfv you’re setting the model-view matrix to identity. Therefore the light will be fixed in view space and the rest of the scene is transformed. As a result, the illumination of the cube changes.

HTH.

Thanks for the response. :slight_smile:

Actually what I want to do eventually is to lit a room and have objects move around. The light will stay fixed in relation to the room. Cube here is one of the object. So in my case, I don’t want to see the cube illumination stay constant as it moves around.

Here’s another object in the scene. I have OBJ loader running and imported a sphere from Maya. The object has been triangulated as my app runs on Android which is a OpenGL ES.

I get strange bands of shades and if I continue to rotate the cube, I see this discontinuity as seen here:

https://picasaweb.google.com/103801513061140283133/Misc#5659686093013529666

Could normals imported from Maya been handled wrong?

Hmm, that link doesn’t work for me.

Looks like the permission was set wrong. Can you view it now?

Nope, it reports: “Page not found!”.

Doh… Lets try this:

https://lh5.googleusercontent.com/-2jYJI…0-04-130825.png

Well, that looks like faulty geometry to me. I guess you’re rendering a sphere which is supposed to be lit smoothly? I’ve never worked with OpenGL on mobile devices, but isn’t GLSL supported to some extent? If so, you could visualize the normals and discover discontinuities quite easily.

Actually the goal is to be able to use any objected created within Maya to be used within my app. This particular model was also created from Maya, exported into OBJ and parsed back into my app. In this OBJ file, all normals are already defined. I don’t need to calculate normals manually.

I wrote the import code with some help from other samples.

Here’s some more illustrations.

Here’s the screen shot from Maya. It shows a model of a fish with normals displayed at each vertex.

https://lh4.googleusercontent.com/-QJ_HgKShm6U/TotZxKe80iI/AAAAAAAAAZs/RpFuFeUKYds/fish_maya.png

And this is the result on my Android phone:

https://lh3.googleusercontent.com/-pmLCB5ifV9E/TotZwpTZFpI/AAAAAAAAAZo/3Lcz34JIZwU/fish_android.png

I’m really puzzled by the vertical patterns shown on the body of the fish. Looking at those normal vectors on the fish, I don’t think I should see any patterns on the body. Most normals point to the same direction.

Without seeing your draw code it’s a bit difficult.
It could be that you have scaled the model?
This may also be scaling the normals. Try enabling GL_NORMALIZE to make all normals unit length.

Good point. Deprecating and removing the fixed-function pipeline from my brain made me overlook this. :wink:

Where should I enable GL_NORMALIZE? Is it ok to do it just before

gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);

? (That didn’t work for me, by the way)

Thanks again. :slight_smile:

IIRC this would just be glEnable(GL_NORMALIZE)…

Normalization should then be done by th GL.

Sorry I wasn’t clear on my question. I can do glEnable(GL_NORMALIZE), no problem there, but where? Should this be done just once at the beginning or per each frame draw?

Thanks. :slight_smile:

No, normally during initialization. There shouldn’t be much reason to disable normalization.

Tried but that didn’t help either.

Perhaps I am interpreting the normal vectors wrong.

For a cube object, this is the content produced directly by Maya:

This file uses centimeters as units for non-parametric coordinates.

mtllib cube.mtl
g default
v -0.965940 0.000000 0.978742
v 0.991195 0.000000 0.978742
v -0.965940 1.651515 0.978742
v 0.991195 1.651515 0.978742
v -0.965940 1.651515 -0.968730
v 0.991195 1.651515 -0.968730
v -0.965940 0.000000 -0.968730
v 0.991195 0.000000 -0.968730
vt 0.375000 0.000000
vt 0.625000 0.000000
vt 0.375000 0.250000
vt 0.625000 0.250000
vt 0.375000 0.500000
vt 0.625000 0.500000
vt 0.375000 0.750000
vt 0.625000 0.750000
vt 0.375000 1.000000
vt 0.625000 1.000000
vt 0.875000 0.000000
vt 0.875000 0.250000
vt 0.125000 0.000000
vt 0.125000 0.250000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 0.000000 -1.000000
vn 0.000000 0.000000 -1.000000
vn 0.000000 0.000000 -1.000000
vn 0.000000 0.000000 -1.000000
vn 0.000000 -1.000000 0.000000
vn 0.000000 -1.000000 0.000000
vn 0.000000 -1.000000 0.000000
vn 0.000000 -1.000000 0.000000
vn 1.000000 0.000000 0.000000
vn 1.000000 0.000000 0.000000
vn 1.000000 0.000000 0.000000
vn 1.000000 0.000000 0.000000
vn -1.000000 0.000000 0.000000
vn -1.000000 0.000000 0.000000
vn -1.000000 0.000000 0.000000
vn -1.000000 0.000000 0.000000
s 1
g pCube2
usemtl initialShadingGroup
f 1/1/1 2/2/2 3/3/3
f 3/3/3 2/2/2 4/4/4
s 2
f 3/3/5 4/4/6 5/5/7
f 5/5/7 4/4/6 6/6/8
s 3
f 5/5/9 6/6/10 7/7/11
f 7/7/11 6/6/10 8/8/12
s 4
f 7/7/13 8/8/14 1/9/15
f 1/9/15 8/8/14 2/10/16
s 5
f 2/2/17 8/11/18 4/4/19
f 4/4/19 8/11/18 6/12/20
s 6
f 7/13/21 1/1/22 5/14/23
f 5/14/23 1/1/22 3/3/24

What I’ve done is to feed vertex and normal values in the order you see here into corresponding arrays. As for the index buffer, I’ve used the first of the 3 values marked under ‘f’ fields. I currently don’t use the second and third values from the ‘f’ fields.

The part that I am questioning right now is how does OpenGL figure out which normals belong to which surface/vertices. As you can see here, the index numbers for normals are not passed along, while vertex coordinates are, when surfaces are defined.

I’ve manually checked these values for the cube and they intuitively made sense so I don’t think Maya is producing a bad set of data.

I appreciate some words of wisdom from anyone. :slight_smile:

Don’t Lightfv before your camera transformations, otherwise the light will move along with the camera. Do it after the transformations.

Makes sense but in this case, I do want the light to move along with the camera since I am simulating a room full of moving objects. Light should stay static in relation to the room, not the objects.

Ah, now I see. :slight_smile:

You cannot use an OBJ to setup a index buffer. The OBJ format does not define indexed geometry which can directly be used with OpenGL. You’ll have to resort to using non-indexed geometry or rewrite your OBJ loader.

For example:

f 1/1/1 2/2/2 3/3/3
f 3/3/3 2/2/2 4/4/4

This is unproblematic, since every vertex index matches the normal and tex coord indices.

f 7/7/13 8/8/14 1/9/15
f 1/9/15 8/8/14 2/10/16

This, however, will alter the the values stored pointed to by index 1 and replace the normal and tex coord with index 1 with the ones identified by indices 15 and 9 respectively.

Remember: For each group of vertex attributes, OpenGL implementations maintain only a single, unique index.

Try to replace your indexed array with a non-indexed one and render using glDrawArrays().