PDA

View Full Version : strange lighting behavior



hideo
01-03-2004, 08:10 PM
ok, I'm learning GL through some book tutorials, and I've gotten up to lighting.

the code I've written is supposed to orbit two cubes around a middle cube which should be where the light source is.

the light is not acting as expected however. even ambient light is all weird. It's lighting up the cubes when they are at a specific angle.

It also seems to be lighting up the cube as a whole instead of the appropriate face.

anyone know what i've done here?

<edit> oops, fixed up a few commenting things




#define WIN32_LEAN_AND_MEAN

//includes
#include <windows.h>
#include <gl/gl.h>
#include <gl/glu.h>
#include <gl/glaux.h>
#include "primatives.h"

//global variables
HDC g_HDC;
bool fullScreen = false;
bool keyPressed[256];//256 keys 256 states

float lightPosition[] = {0.0f, 0.0f, 1.0f, 0.0f }; // global light is directional

float diffuseLight[] = {1.0f, 1.0f, 1.0f, 1.0f}; // difuse light
float diffuseMat[] = {1.0f, 1.0f, 1.0f, 1.0f}; // difuse material

float ballDiffuse[] = {0.5f, 0.5f, 0.0f, 1.0f }; // ball diffuse
float ballSpecular[] = {1.0f, 1.0f, 1.0f, 1.0f }; // ball specular
float ballPosition[] = {0.0f, 0.0f, 0.0f, 1.0f }; // ball position

float angle=0.0f;
float cubeAngle=0.0f;

void initialize()
{
//initialise things like lighting and initial gl states

glEnable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);

//global diffuse light
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
glEnable(GL_LIGHT0);

//sun light
glLightfv(GL_LIGHT1, GL_DIFFUSE, ballDiffuse);
glLightfv(GL_LIGHT1, GL_SPECULAR, ballSpecular);
glEnable(GL_LIGHT1);

//diffuse material for objects
glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuseMat);

//color tracking
glEnable(GL_COLOR_MATERIAL);

//smooth shading
glShadeModel(GL_SMOOTH);



//clear background to black
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
}

void render()
{
//do rendering here
//clear screen and depth buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();

//both spheres use same rotation speed
if(angle >= 359.9f)
angle=0;
if(cubeAngle >= 359.9f)
cubeAngle=0;
//angle+=0.5f;

//move back 15 units
glTranslatef(0.0f,0.0f,-15.0f);



//draw the sun ball
glPushMatrix();
glColor3f(1.0f,1.0f,0.0f);
glTranslatef(ballPosition[0], ballPosition[1], ballPosition[2]);
//set light position of the ball
glLightfv(GL_LIGHT1, GL_POSITION, ballPosition);
//auxSolidSphere(0.5f);
//using cube instead until i get linking working
drawCube(0.5f);
glPopMatrix();

//draw opaque sphere
glPushMatrix();
glRotatef(angle, 0.0f, 1.0f, 0.0f);//orbit the yellow cube
glTranslatef(0.0f, 0.0f, 6.0f);
glRotatef(cubeAngle, 0.0f, 1.0f, 0.0f); //spin on their own axis
glColor4f(1.0f, 0.2f, 0.2f, 1.0f);
//auxSolidSphere(2.0f);
//using cube instead until i get linking working
drawCube(2.0f);
glPopMatrix();

//enable blending
glEnable(GL_BLEND);

//enable read only depth buffer
glDepthMask(GL_FALSE);

//set blend function
glBlendFunc(GL_SRC_ALPHA, GL_ONE);

//draw transparant sphere
glPushMatrix();
glRotatef(angle, 0.0f, 1.0f, 0.0f);//orbit the yellow cube
glTranslatef(0.0f,0.0f,-6.0f);
glRotatef(cubeAngle, 0.0f, 1.0f, 0.0f); //spin on their own axis
glColor4f(0.0f,0.5f,0.5f,0.3f);
//auxSolidSphere(2.0f);
//using cube instead until i get linking working
drawCube(2.0f);
glPopMatrix();

//set depth buffer as writable again
glDepthMask(GL_TRUE);

//disable bleding
glDisable(GL_BLEND);

glFlush();
SwapBuffers(g_HDC);
}


void SetupPixelFormat(HDC hDC)
{
int nPixelFormat; // our pixel format index
static PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR), //size of structure
1, //default ver
PFD_DRAW_TO_WINDOW | //window-drawing support
PFD_SUPPORT_OPENGL | //opengl support
PFD_DOUBLEBUFFER, //double buffering support
PFD_TYPE_RGBA, //RGBA color mode
32, //32 bit color mode
0,0,0,0,0,0, //ignore color bits, non palletized mode
0, //no alpha buffer
0, //ignore shift bit
0, //no accumulation buffer
0,0,0,0, //ignore accumulation buffer
16, // 16 bit z-buffer size
0, //no stencil buffer
0, //no auxiliary buffer
PFD_MAIN_PLANE, //main drawing plane
0, //reserved
0,0,0}; //layer masks ignored

//choose best matching pixel format
nPixelFormat = ChoosePixelFormat(hDC, &amp;pfd);

//set pixel format to device context
SetPixelFormat(hDC, nPixelFormat, &amp;pfd);
}

//the windows procedure event handler
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HGLRC hRC; //rendering context
static HDC hDC; //device context
int width, height; //window width and height

switch(message)
{
case WM_CREATE: //window is being created

hDC = GetDC(hwnd); //retrieve device context for the window
g_HDC = hDC; //global device context?
SetupPixelFormat(hDC);

hRC = wglCreateContext(hDC); //create WGL rendering context
wglMakeCurrent(hDC, hRC); //make it current

return 0;

case WM_CLOSE: // windows is closing
wglMakeCurrent(hDC,NULL); //deselect current rendering context
wglDeleteContext(hRC); //delete it

PostQuitMessage(0); //let the queue know we're leaving

return 0;

case WM_SIZE:
height = HIWORD(lParam); //retrieve width
width = LOWORD(lParam); //and height

if (height==0)
height=1; //prevent /0 error

glViewport(0,0,width,height); //reset viewport
glMatrixMode(GL_PROJECTION); //set projection matrix
glLoadIdentity(); //clear projection matrix

//calculate aspect ratio of window
gluPerspective(54.0f, (GLfloat) width / (GLfloat) height, 1.0f, 1000.0f);

glMatrixMode(GL_MODELVIEW); // set modelview matrix
glLoadIdentity(); // clear it

return 0;

case WM_KEYDOWN:
keyPressed[wParam] = true;
return 0;
case WM_KEYUP:
keyPressed[wParam] = false;
return 0;

default:
break;
}
return (DefWindowProc(hwnd,message,wParam,lParam));//if i don't have to handle it, let the default handler do something
}

//windows main
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
WNDCLASSEX windowClass; // windows class
HWND hwnd; // window handle
MSG msg; //mesage
bool done; //exit flag

DWORD dwExStyle; //extended window style
DWORD dwStyle; //window style

RECT windowRect;
const char classString[] = "MyClass";

int width = 800;
int height = 600;
int bits=32;

windowRect.left = (long)0;
windowRect.right = (long)width;
windowRect.top=(long)0;
windowRect.bottom = (long)height;

//fill out the cclass structure
windowClass.cbSize = sizeof(WNDCLASSEX);
windowClass.style = CS_HREDRAW | CS_VREDRAW;
windowClass.lpfnWndProc = WndProc;
windowClass.cbClsExtra = 0;
windowClass.cbWndExtra = 0;
windowClass.hInstance = hInstance;
windowClass.hIcon = LoadIcon(NULL,IDI_APPLICATION);
windowClass.hCursor = LoadCursor(NULL,IDC_ARROW);
windowClass.hbrBackground = NULL;
windowClass.lpszMenuName= NULL;
windowClass.lpszClassName = classString;
windowClass.hIconSm = LoadIcon(NULL, IDI_WINLOGO);

//register the windows class
if(!RegisterClassEx(&amp;windowClass))
return 0;

if (fullScreen)
{
DEVMODE dmScreenSettings; //device mode
memset(&amp;dmScreenSettings,0,sizeof(dmScreenSettings ));
dmScreenSettings.dmSize = sizeof(dmScreenSettings);
dmScreenSettings.dmPelsWidth = width;
dmScreenSettings.dmPelsHeight = height;
dmScreenSettings.dmBitsPerPel = bits;
dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;

if (ChangeDisplaySettings(&amp;dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
{
MessageBox(NULL, "FULL SCREEN FAILED", NULL, MB_OK);
fullScreen = false;
}
}

if(fullScreen)
{
dwExStyle = WS_EX_APPWINDOW;
dwStyle=WS_POPUP;
ShowCursor(false);
}
else
{
dwExStyle = WS_EX_APPWINDOW|WS_EX_WINDOWEDGE;
dwStyle = WS_OVERLAPPEDWINDOW;
}

AdjustWindowRectEx(&amp;windowRect, dwStyle, false, dwExStyle);

hwnd = CreateWindowEx(NULL,
classString,
"OPENGLROBOT",
dwStyle | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
0,0,
windowRect.right - windowRect.left,
windowRect.bottom - windowRect.top,
NULL,
NULL,
hInstance,
NULL);
//check if window is created
if(!hwnd)
return 0;

ShowWindow(hwnd, SW_SHOW);
UpdateWindow(hwnd);

done = false;
initialize();

//main message loop
while (!done)
{
PeekMessage(&amp;msg, hwnd, NULL, NULL, PM_REMOVE);

if(msg.message == WM_QUIT)
done = true;
else if (keyPressed[VK_ESCAPE])
done=true;
else
{
//check for key presses in here
if(keyPressed['A'])
angle-=1.0f;
if(keyPressed['D'])
angle+=1.0f;
if(keyPressed['Q'])
cubeAngle--;
if(keyPressed['E'])
cubeAngle++;
render();
TranslateMessage(&amp;msg);
DispatchMessage(&amp;msg);
}
}
if (fullScreen)
{
ChangeDisplaySettings(NULL,0);
ShowCursor(true);
}
return msg.wParam;
}

[This message has been edited by hideo (edited 01-03-2004).]

01-04-2004, 02:49 AM
Hehe, toobad, you have not pasted the only relevant code ... http://www.opengl.org/discussion_boards/ubb/smile.gif What is exactly in your drawCube(0.5f) ?




//auxSolidSphere(0.5f);
//using cube instead until i get linking working
drawCube(0.5f);


In fact you need to specify explicitly a normal at each vertex for the lighting to work properly. Else you get the same color everywhere ... Really, try to get linking working because auxSolidSphere() sets the normals automatically, at least the glut ones do it :
glutSolidTeapot(0.5f);

Good luck.

hideo
01-04-2004, 03:28 PM
yeah thanks, i figured it out at approx 1:30am this morning :p GLUT doesn't seem to like bcc32 so I've spent the rest of the time getting the command line visual studio compilers