Lighting and scaling, problems

Started by
6 comments, last by Daivuk 17 years, 7 months ago
I have a problem related to the combination of these. My geometry with a scale(using glScalef) of 1.0 appear correctly lighted, but objects above appear to dark and below they are way to bright. Is there some obvious thing that may be causing this?
Advertisement
what exactly do you mean when you say "objects above appear to dark and below they are way to bright". Do you mean any object being drawn below (as in a lesser y-value) the original object is being drawn too brightly and objects drawn above (as in a greater y-value) are being drawn too dark?

This doesn't seem like it should have much to do with the scaling unless for some odd reason your normals are getting scaled as well. The most likely culprit is how you've set up your lighting model in OpenGL. Can you please post the code that initializes your lighting, and possibly some of the actual drawing code itself?

Thanks
I mean scale above and below 1.0.

Here's the render function:

void drawScreen() {	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	camera.look();	float m[16];	glEnable(GL_LIGHTING);	glEnable(GL_LIGHT0);	glLightfv(GL_LIGHT0, GL_AMBIENT, light.ambient);	glLightfv(GL_LIGHT0, GL_DIFFUSE, light.diffuse);	glLightfv(GL_LIGHT0, GL_SPECULAR, light.specular);	glLightfv(GL_LIGHT0, GL_POSITION, light.position);	glEnableClientState(GL_VERTEX_ARRAY);	glEnableClientState(GL_NORMAL_ARRAY);	for(size_t i = 0; i < objects.size(); ++i) {		Object *obj = objects;		Geometry *g = obj->geometry;		Material *mat = obj->material;		Transform &t = obj->transform->world;		t.rotate.toMatrix(m);		glPushMatrix();		glTranslatef(t.translate.x, t.translate.y, t.translate.z);		glScalef(t.scale.x, t.scale.y, t.scale.z);		glMultMatrixf(m);		glMaterialfv(GL_FRONT, GL_AMBIENT, mat->ambient);		glMaterialfv(GL_FRONT, GL_DIFFUSE, mat->diffuse);		glMaterialfv(GL_FRONT, GL_SPECULAR, mat->specular);		glMaterialfv(GL_FRONT, GL_EMISSION, mat->emission);		glMaterialf(GL_FRONT, GL_SHININESS, mat->shininess);		glVertexPointer(3, GL_FLOAT, 0, (float *)&g->vertices[0]);		glNormalPointer(GL_FLOAT, 0, (float *)&g->normals[0]);		glDrawElements(GL_TRIANGLES, g->indices.size(), GL_UNSIGNED_SHORT, &g->indices[0]);		glPopMatrix();	}	glDisableClientState(GL_NORMAL_ARRAY);	glDisableClientState(GL_VERTEX_ARRAY);	SDL_GL_SwapBuffers();}
If the current transformation matrix contains scaling then you need to call glEnable(GL_NORMALIZE) so that OpenGL makes all normals unit length.
deathkrushPS3/Xbox360 Graphics Programmer, Mass Media.Completed Projects: Stuntman Ignition (PS3), Saints Row 2 (PS3), Darksiders(PS3, 360)
Thanks, that was indeed the problem!
Keep in mind that you really shouldn't use glEnable(GL_NORMALIZE). It can really slow your program down. Instead, you'll want to either A) Don't use glScale(), just modify the location of the vertices yourself B) Re-normalize the normals yourself after scaling and save those, that way you only have to re-normalize once. Calling glEnable(GL_NORMALIZE) has to re-calculate the normals every frame (I believe).
Quote:Original post by Mantear
Calling glEnable(GL_NORMALIZE) has to re-calculate the normals every frame (I believe).


It normalizes the normals. Depending if you are vertex limited or not, it will slow down, or you won't notice.
There is another option, I think call AUTO_NORMALIZE.
If you use uniform scale, enable this one instead because it is faster.
Sig: http://glhlib.sourceforge.net
an open source GLU replacement library. Much more modern than GLU.
float matrix[16], inverse_matrix[16];
glhLoadIdentityf2(matrix);
glhTranslatef2(matrix, 0.0, 0.0, 5.0);
glhRotateAboutXf2(matrix, angleInRadians);
glhScalef2(matrix, 1.0, 1.0, -1.0);
glhQuickInvertMatrixf2(matrix, inverse_matrix);
glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);
Personnaly I use :
glEnable(GL_RESCALE_NORMAL);

This topic is closed to new replies.

Advertisement