Problem with Global Ambient Light

I want to set the global ambient light with these calls

//set the light model
float vAmbientLightBright[4] = {0.5f, 0.5f, 0.5f, 1.0f};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, vAmbientLightBright);
glEnable(Gl.GL_DEPTH_TEST);
glEnable(Gl.GL_LIGHTING);

//draw something

The effect is that I don’t see anything, although the ambient light’s intensity is at maximum which should lead to a very bright overall scene or am I wrong?
A variation of vAmbientLightBright to other values doesn’t yield a different effect, the scene stays black. (I use a geforce6600 gt)

I do remember that this worked on my ati radeon9000 mobility.

However if I don’t seperate the Gl.GLIGHTING enable from the the GL_DEPTH_TEST enable like this

float vAmbientLightBright[4] = {0.5f, 0.5f, 0.5f, 1.0f};
glLightModelfv(Gl.GL_LIGHT_MODEL_AMBIENT, vAmbientLightBright);
glEnable(Gl.GL_DEPTH_TEST | Gl.GL_LIGHTING);

//draw something

The scene is now visible although varying vAmbientLightBright doesn’t contribute either (changing all floats to 0.0f or 1.0f means the same).

Does anyone have a good reason for this or can see my mistake.

do you have a glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, …) call somewhere?

no, I use GL_COLOR_MATERIAL to draw a simple triangle and use the color values as ambient and diffuse material properties.

But the material settings are not the problem since the scene is visible in a combined call with glEnable(GL_SOMETHING | GL_LIGHTING);

but is not visible with a single call
glEnable(GL_LIGHTING);

this is for my geforce6600gt

very strange. can you post some more code? which os/driver are you using?

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <windowsx.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <wingdi.h>

#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "glu32.lib")
#pragma comment(lib, "gdi32.lib")

#define ERRORMSG(text, label) MessageBox(hMainWindow, text, label, MB_OK);

//Window
#define WIDTH 640
#define HEIGHT 480
#define BPP 32
#define LEFT 0
#define TOP 0
#define WNDCLASSNAME "MainWindowClass"

//Viewing Volume
#define HORZ 100.0d //left and right extent
#define VERT 100.0d //top and bottom extent
#define BACK 100.0d //near and far clipping plane

//keep track of x and y mouse coordinates
int x = 0;
int y = 0;
int i = 0;
int j = 0;
int bSwap = 0;

HWND hMainWindow = NULL; //window 
HDC hMainDC = NULL; //window's device context
HGLRC hGLRC = NULL; //window's rendering context

//set pixelformat descriptor
int setDCPixelFormat(HDC dc, HGLRC *hrc);
int releaseDCPixelFormat(HDC dc, HGLRC *hrc);

//put your rendering stuff here
void setupGL();
void render();

//resize window
void resizeWindow(int w, int h);

float vAmbientLightBright[4]	= {0.8f, 0.8f, 0.8f, 1.0f};
float vAmbientLightDark[4]		= {0.2f, 0.2f, 0.2f, 1.0f};

float vMaterialAmbientAndDiffuse[4]= {0.8f, 0.8f, 0.8f, 1.0f};

void setupGL()
{
	glLightModelfv(GL_LIGHT_MODEL_AMBIENT, vAmbientLightBright);
	glEnable(GL_DEPTH_TEST | GL_LIGHTING);
	//glEnable(GL_LIGHTING);
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
	glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
	glEnable(GL_COLOR_MATERIAL);
}

void render()
{
//local variables and identifiers
//main stuff
	//clear buffers
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	//draw triangle
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	//triangle
	glBegin(GL_TRIANGLES);
		glColor3f(1.0f, 0.0f, 0.0f); glVertex3f(-0.5f, 0.0f, 0.5f);
		glColor3f(0.5f, 0.0f, 0.0f); glVertex3f( 0.5f, 0.0f, 0.5f);
		glColor3f(0.0f, 0.0f, 5.0f); glVertex3f( 0.0f, 0.5f, 0.5f);
	glEnd();


	glFlush(); //releaase possibly stored calls
	//end
}

void resizeWindow(int w, int h)
{
	//local variables and identifiers
	//main stuff
	glViewport(0, 0, w, h); //set new viewport
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();

	glOrtho(-WIDTH, WIDTH, -HEIGHT, HEIGHT, -10.0f, 10.0f);
	//end
}

int setDCPixelFormat(HDC dc, HGLRC *hrc)
{
	//local variables and identifiers
	int iPixelFormat = 0; //used in enumpixelformat
	PIXELFORMATDESCRIPTOR pfd;
	//main stuff
	pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
	pfd.nVersion = 1;
	pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER;
	pfd.iPixelType = PFD_TYPE_RGBA;
	pfd.cColorBits = BPP;
	pfd.cRedBits  = 8;
	pfd.cGreenBits= 8;
	pfd.cBlueBits = 8;
	pfd.cAlphaBits= 0;
	pfd.cAccumAlphaBits = 0;
	pfd.cDepthBits = 16;
	pfd.cStencilBits= 0;
	pfd.cAuxBuffers = 0;
	pfd.iLayerType  = PFD_MAIN_PLANE;
	pfd.bReserved = 0;
	pfd.dwLayerMask = 0;
	pfd.dwVisibleMask=0;
	pfd.dwDamageMask =0;

	iPixelFormat = ChoosePixelFormat(dc, &pfd);
	//get closest matching pixelformat
	if(iPixelFormat == 0)
	{
		//error
		ERRORMSG("failed ChoosePixelFormat", "error");
		return (-1);
	}

	//set our pixelformat
	if(SetPixelFormat(dc, iPixelFormat, &pfd) == FALSE)
	{
		//error
		ERRORMSG("failed SetPixelFormat", "error");
		return (-1);
	}

	//get rendering context
	*hrc = wglCreateContext(dc);
	if(hGLRC == NULL)
	{
		ERRORMSG("failed wglCreateContext", "error");
		return (0);
	}

	//make it current
	wglMakeCurrent(dc, *hrc);
	//end
	return (0);
}

int releaseDCPixelFormat(HDC dc, HGLRC *hrc)
{
	//local variables and identifiers
	//main stuff
	wglMakeCurrent(dc, NULL);
	wglDeleteContext(*hrc);
	//end
	return (0);
}


LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	//local variables and identifiers
	HDC hDC = NULL;
	PAINTSTRUCT paintStruct;
	//main stuff
	switch(uMsg)
	{
	case WM_CREATE:
		{
			//your initialization
		}
		break;
	case WM_PAINT:
		{
			//your repainting code goes here
		}
		break;
	case WM_DESTROY:
		{
			//it's all over
			PostQuitMessage(0);
		}
		break;
	case WM_KEYDOWN:
		{
			switch(wParam)
			{
			case VK_ESCAPE:
				//if escape key then quit application
				PostMessage(hWnd, WM_QUIT, wParam, lParam);
				break;
			default:
				break;
			}
		}
	case WM_SIZE:
		{
			//reorient OpenGL
			//resizeWindow(LOWORD(lParam), HIWORD(lParam));
		}
		break;
	case WM_MOUSEMOVE:
		{
			/*
			wParam describes various mouse states
			lParam describes position on screen (loword = x, hiword = y)
			*/
			x = LOWORD(lParam);
			y = HIWORD(lParam);
			if((wParam & MK_LBUTTON) == MK_LBUTTON) //left mouse
			{
			}
			else if((wParam & MK_MBUTTON) == MK_MBUTTON) //middle mouse
			{
			}
			else if((wParam & MK_RBUTTON) == MK_RBUTTON) //right mouse
			{
			}
		}
		break;
	default:
		return (DefWindowProc(hWnd, uMsg, wParam, lParam));
	}
	//end
	return (0);
}

int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
{
	//local variables and identifiers
	WNDCLASS windowClass;
	MSG Msg;
	HDC myDC = NULL;
	DEVMODE oldMode, newMode;
	//main stuff
	/*
	get current display mode
	*/
	glGetString(GL_VENDOR);
	EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &oldMode);
	newMode.dmSize = sizeof(DEVMODE);
	newMode.dmFields= DM_PELSHEIGHT | DM_PELSWIDTH | DM_BITSPERPEL;
	newMode.dmBitsPerPel = BPP;
	newMode.dmPelsHeight = HEIGHT;
	newMode.dmPelsWidth  = WIDTH;
	//change to new Mode
	if(ChangeDisplaySettings(&newMode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
	{
		//error
		ERRORMSG("failed changeDisplaySettings", "error");
		return (-1);
	}
	/*
	fill wndclass structure, register wndclass, create window, show window
	and get messages from message queue
	*/
	windowClass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_OWNDC;
	windowClass.lpfnWndProc = (WNDPROC)WindowProc;
	windowClass.cbClsExtra = 0;
	windowClass.cbWndExtra = 0;
	windowClass.hInstance = hInstance;
	windowClass.hbrBackground = GetStockObject(WHITE_BRUSH);
	windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
	windowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	windowClass.lpszClassName = WNDCLASSNAME;
	windowClass.lpszMenuName = NULL;
	if(!RegisterClass(&windowClass))
	{
		//error ...
		ERRORMSG("failed RegisterClass()", "Error");
		return (-1);
	}
	hMainWindow = CreateWindow(WNDCLASSNAME, "My Window", 
								WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
								LEFT, TOP, 
								WIDTH, HEIGHT,
								NULL, NULL, hInstance, NULL);
	if(!hMainWindow)
	{
		//error ...
		ERRORMSG("failed CreateWindow()", "Error");
		return (-1);
	}
	myDC = GetDC(hMainWindow);
	if(setDCPixelFormat(myDC, &hGLRC) == -1)
	{
		ChangeDisplaySettings(&oldMode, 0);
		return (-1);
	}	
	setupGL();
	ReleaseDC(hMainWindow, myDC);
	ShowWindow(hMainWindow, SW_SHOW);

	while(1)
	{
		if(PeekMessage(&Msg, hMainWindow, 0, 0, PM_REMOVE))
		{
			//msg in queue
			if(Msg.message == WM_QUIT)
			{
				//break and return to windows
				break;
			}

			TranslateMessage(&Msg);

			DispatchMessage(&Msg);
		}
		//your useful stuff
		if((GetAsyncKeyState(VK_UP) & 0x8000) == 0x8000) //MSB is set?
		{
			i = (i+1) % 360;
		}
		if((GetAsyncKeyState(VK_DOWN) & 0x8000) == 0x8000) //MSB is set?
		{
			i = (i-1) % 360;
		}
		if((GetAsyncKeyState(VK_LEFT) & 0x8000) == 0x8000) //MSB is set?
		{
			j = (j+1) % 360;
		}
		if((GetAsyncKeyState(VK_RIGHT)& 0x8000) == 0x8000) //MSB is set?
		{
			j = (j-1) % 360;
		}
		myDC = GetDC(hMainWindow); //obtain device context
		render(myDC); //paint your stuff
		SwapBuffers(myDC);
		ReleaseDC(hMainWindow, myDC); //release device context so that others may use it
	}
	//free rendering context
	myDC = GetDC(hMainWindow);
	releaseDCPixelFormat(myDC, &hGLRC);
	ReleaseDC(hMainWindow, myDC);

	ChangeDisplaySettings(&oldMode, 0);
	//end
	return (0);
}  

I use a geforce6600gt with the latest drivers

this is the complete code but I guess only the top part is relevant. And as stated before if I change

glEnable(GL_DEPTH_TEST | GL_LIGHTING);
//glEnable(GL_LIGHTING);

to

//glEnable(GL_DEPTH_TEST | GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);

I don’t see anything or altering

glLightModelfv(GL_LIGHT_MODEL_AMBIENT, vAmbientLightBright);

to

glLightModelfv(GL_LIGHT_MODEL_AMBIENT, vAmbientLightDark);

produces no effect

hm…at the top you define void render(), but in the loop you call render(myDC)…i have not done soo much programming in windows, so i’m not sure if you have to get a DC each time you redraw the scene, i think it’s not necessary when you create the window with CS_OWNDC.

what is actually wrong? do you see a black triangle or do you see nothing at all? i’m not sure if this is only a lighting problem. what do you see when you do not try to enable lighting at all?

the dc thing is not necessary you are right - actually there is no use in the render function for the device context.

If I glDisable(GL_LIGHTING) or do not explicitly enable it I see the triangle. If I enable Lighting in the combined (with Depth test or another constant) I see the same triangle. If I use separate calls I don’t see anything.

On my notebook’s ati card this works (separate calls and varying the intensity of global illumination).

hm…no idea. maybe you have made some mistake in creating the window, the gl context etc. i think you should try to use glut as a first step, because with glut you get a window that is correctly setup.

I don’t think it is in the window’s setup.

Do I need to enable GL_LIGHT0 to get the global illumination because if I glEnable(GL_LIGHT0);

It works. Not quite sure or it was a driver’s issue I installed the international NVidia drivers and now it seems to work :frowning: . The confusion of a whole morning saved by the driver :slight_smile: (at least I hope so)

no, GL_LIGHT0 is not necessary for ambient light.

hmm well then I have to undergo some more testing since it seems to work now with C, but I use Tao for .Net integration and the problem remained.

glEnable does not take bit mask of states to enable so it is not possible to combine several values using the “|” operator. If you look into gl.h at values for GL_DEPTH_TEST (0x0B71) and GL_LIGHTING (0xb50) you will see that by ORing them together you will get back value for GL_DEPTH_TEST. Because of this, lighting is not enabled and colors specified by glColor3f are used directly and you see something. However this is just lucky coincidence and you may have enabled entirely different state.

tnx for your answer I found the same yesterday as I had a look into the manual and I bit myself in ***
because of that mistake :smiley: