Sign in to follow this  
Colossus_1

How to enlight the whole scene while moving with camera ?

Recommended Posts

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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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,

Share this post


Link to post
Share on other sites
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).

Share this post


Link to post
Share on other sites
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 ?

Share this post


Link to post
Share on other sites

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 ?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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 ?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this