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.
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.
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:
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.
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.
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?
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.
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.
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().