PDA

View Full Version : Problem with Global Ambient Light



powerpad
04-07-2005, 09:26 PM
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 somethingThe 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 somethingThe 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.

RigidBody
04-07-2005, 09:33 PM
do you have a glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, ...) call somewhere?

powerpad
04-07-2005, 09:44 PM
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

RigidBody
04-07-2005, 10:05 PM
very strange. can you post some more code? which os/driver are you using?

powerpad
04-07-2005, 10:33 PM
#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, &amp;pfd);
//get closest matching pixelformat
if(iPixelFormat == 0)
{
//error
ERRORMSG("failed ChoosePixelFormat", "error");
return (-1);
}

//set our pixelformat
if(SetPixelFormat(dc, iPixelFormat, &amp;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, &amp;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(&amp;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(&amp;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, &amp;hGLRC) == -1)
{
ChangeDisplaySettings(&amp;oldMode, 0);
return (-1);
}
setupGL();
ReleaseDC(hMainWindow, myDC);
ShowWindow(hMainWindow, SW_SHOW);

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

TranslateMessage(&amp;Msg);

DispatchMessage(&amp;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)&amp; 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, &amp;hGLRC);
ReleaseDC(hMainWindow, myDC);

ChangeDisplaySettings(&amp;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

RigidBody
04-07-2005, 10:54 PM
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?

powerpad
04-07-2005, 11:02 PM
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).

RigidBody
04-07-2005, 11:27 PM
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.

powerpad
04-07-2005, 11:39 PM
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 :( . The confusion of a whole morning saved by the driver :) (at least I hope so)

RigidBody
04-07-2005, 11:56 PM
no, GL_LIGHT0 is not necessary for ambient light.

powerpad
04-08-2005, 12:53 AM
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.

04-09-2005, 05:56 AM
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.

powerpad
04-09-2005, 08:37 AM
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 :D