How to enlight the whole scene while moving with camera ?

Started by
8 comments, last by Colossus_1 19 years, 5 months ago
Hi, I'm developing a 3d scene editor. The problem is I'm not able to give light to the entire scene following the camera (I do not use gluLookAt). Please look at the screenshot; you will see that the building is partially enlightned while the upper part is dark: http://cpsed.sourceforge.net/ These are the settings I use for light:

void GLWidget::initializeGL()
{
	glClearColor( 0.4 , 0.4 , 0.4 , 1.0 );
	glMatrixMode ( GL_MODELVIEW );
	glLoadIdentity();
	glEnable (GL_RESCALE_NORMAL);
	glDepthFunc (GL_LEQUAL);
	glEnable (GL_COLOR_MATERIAL);
	glEnable (GL_DEPTH_TEST);
	
	GLfloat LightAmbient[]= { 0.5f, 0.5f, 0.5f, 1.0f };
	GLfloat LightDiffuse[]= { 1.0f, 1.0f, 1.0f, 1.0f };
	GLfloat LightPosition[]= { 0.0f, 0.0f, 700.0f, 1.0f };
	
	glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmbient);
  	glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDiffuse);
  	glLightfv(GL_LIGHT0, GL_POSITION,LightPosition);
	glEnable(GL_LIGHT0);
	glEnable(GL_LIGHTING);
	mode = GL_RENDER;
}





and this is the drawing routine:

void GLWidget::paintGL()
{
	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
	glMatrixMode( GL_MODELVIEW );
	glLoadIdentity();
	SetCamera();
	for ( std::map< GLuint , string >::iterator i= GlWindowClass->DisplayList.begin(); i != GlWindowClass->DisplayList.end(); i++)
	{
		unsigned int index = i->first;
		glPushMatrix();
			if ( mode == GL_SELECT ) glPushName ( index );
			glTranslatef ( Model [ index-1 ].x , Model [ index-1 ].y  , Model [ index-1 ].z );
			glRotatef ( Model [ index-1 ].xrot , 1.0f , 0.0f , 0.0f );
			glRotatef ( Model [ index-1 ].yrot , 0.0f , 1.0f , 0.0f );
			glRotatef ( Model [ index-1 ].zrot , 0.0f , 0.0f , 1.0f );
			glScalef ( Model [ index-1 ].sx , Model [ index-1 ].sy  , Model [ index-1 ].sz );
			glCallList ( index );
			if ( mode == GL_SELECT ) glPopName ();
		glPopMatrix();
	}
}





Follows the set camera:

void GLWidget::SetCamera()
{
	glTranslatef ( Tx, Ty, Depth );
	glRotatef ( AngleX, 1, 0, 0 );
    	glRotatef ( AngleY, 0, 1, 0 );
    	glRotatef ( AngleZ, 0, 0, 1 );
}





What is wrong ? Colossus
ColossusCpsed,a Linux OpenGL 3D scene editorhttp://cpsed.sourceforge.net
Advertisement
If you are trying to achieve a global ambient light level, try something like the following:

    Glfloat global_ambient[] = { 0.5f, 0.5f, 0.5f, 1.0f };    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, global_ambient);


This works independent of any individual lights and applies to the entire scene.
Thank you for replying, the situation improved a bit, now the upper part of the building is a bit less dark but still dark compared to the bottom part who is well enlightened. Is it a matter of the values I gave to the glLight functions ? If so how can I calculate the float values to pass to the functions ?

Thanks for your time,
ColossusCpsed,a Linux OpenGL 3D scene editorhttp://cpsed.sourceforge.net
You could simply move GL_LIGHT0 when you move the camera.

In the SetCamera function, you could just put some new code for glLightfv(GL_LIGHT0, GL_POSITION, aNewVectorValue), where "aNewVectorValue" is the light's position after the camera has moved (easiest would be to keep it at the exact position of the camera).
Quote:Original post by azjerei
(easiest would be to keep it at the exact position of the camera).


Thank you. Since I don't use gluLookAt, the exact values of the camera which I shall use in glLightfv(GL_LIGHT0, GL_POSITION .... ) are those in glTranslate: ?

void GLWidget::SetCamera(){	glTranslatef ( Tx, Ty, Depth );


Is it correct ?
ColossusCpsed,a Linux OpenGL 3D scene editorhttp://cpsed.sourceforge.net
Most likely, those are the values you should use.
void GLWidget::SetCamera(){	GLfloat LightPosition[]= { Tx, Ty, Depth, 1.0f };	glLightfv(GL_LIGHT0, GL_POSITION , LightPosition);	glTranslatef ( Tx, Ty, Depth );	glRotatef ( AngleX, 1, 0, 0 );    	glRotatef ( AngleY, 0, 1, 0 );    	glRotatef ( AngleZ, 0, 0, 1 );}


It behaves the same. Only the lower part of the building is enlightned; the same if I put the glLightfv call AFTER the glRotatef. Any other idea ?
ColossusCpsed,a Linux OpenGL 3D scene editorhttp://cpsed.sourceforge.net
If you are trying to get a constant light across the entire scene, don't use an individual light at all. Just adjust the values of the global ambient light to the desired light level. ((1.0,1.0,1.0) being fully lit).

As long as you leave the ambient level low and use a point light, you are going to get areas of the scene closest to the camera brighter than areas farther away.

If you want areas closer to be brighter, then keep the point light, but brighten your global ambient light values to make the rest of the scene visible.
your light is a positional light (cause the last number is not 0.0) perhaps u can change it to a directional one, or else make the lights attenuation higher, or else perhaps the scene youre trying to light is not tesselated enuf
Ok, these are my light settings:

GLfloat LightAmbient[]= { 1.0f, 1.0f, 1.0f, 1.0f };	GLfloat LightDiffuse[]= { 1.0f, 1.0f, 1.0f, 1.0f };	GLfloat LightPosition[]= { 1.0f, 1.0f, 0.0f, 0.0f };	GLfloat Specular[]= { 1.0f, 1.0f, 1.0f, 1.0f };		glColorMaterial ( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE );	glEnable ( GL_COLOR_MATERIAL ) ;		glLightfv (GL_LIGHT0, GL_POSITION , LightPosition);	glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmbient);  	glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDiffuse);	glLightfv(GL_LIGHT0, GL_SPECULAR, Specular);


The upper part of the building is less dark but still dark. Are the settings above correct ?
ColossusCpsed,a Linux OpenGL 3D scene editorhttp://cpsed.sourceforge.net

This topic is closed to new replies.

Advertisement