Hi!
I am using an overlay plane to render highlighted objects in the scene. But I am having trouble with the shading. All objects turn out gray and look flat shaded.
I am using a Quadro4 900 XGL. The overlay plane uses a 8 bit color index mode. I fill the entire palette with green color range.
If I disable lighting I get the correct color, but when lighting is enabled everything turns gray.
I have also tested this on a Wildcat 6210 and the result there is that everything turns black in lighted mode. But as the nVidia card the unlighted mode works as it should.
Does anybody know what I am doing wrong?
/Fredrik
The code is posted below:
This program shows two spheres. The red one is drawn in the main plane. The green is rendered in the overlay plane. Clipping planes are used to show half of each. In unlighted mode the clipping does not seem to work.(If you wonder why only the overlay sphere is visible in )
#include <windows.h>
#include <math.h>
#include <gl\gl.h>
#include <gl\glu.h>
#include <gl\glaux.h>
HDC hDC=NULL;
HGLRC hRC=NULL;
HGLRC hLRC=NULL;
HWND hWnd=NULL;
HINSTANCE hInstance;
bool keys[256]; // Array Used For The Keyboard Routine
bool layerMode = true;
bool layerColorModeIndex = true;
bool useLighting = true;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int getPF(HDC hDC, const PIXELFORMATDESCRIPTOR *pfd);
GLvoid ReSizeGLScene(GLsizei width, GLsizei height)
{
if (height==0) // Prevent A Divide By Zero By
{
height=1;
}
wglMakeCurrent(hDC,hRC);
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
wglMakeCurrent(NULL, NULL);
wglMakeCurrent(hDC,hLRC);
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
wglMakeCurrent(NULL, NULL);
}
void drawLight()
{
int _target = 0;
float _direction[] = { 0, 0, -1};
float _intensity = 1.0f;
float _ambientIntensity = 0.0f;
float _color[3] = {1.0, 1.0, 1.0};
int target = _target + GL_LIGHT0;
glEnable(target);
static GLfloat vec[4];
static GLfloat spec[] = {1.0f, 1.0f, 1.0f, 1.0f};
float mag = (float)sqrt( _direction[0]_direction[0] +
_direction[1]_direction[1] +
_direction[2]*_direction[2] );
if ( mag != 0 ) mag = 1.0f/mag;
vec[0] = -_direction[0]*mag;
vec[1] = -_direction[1]*mag;
vec[2] = -_direction[2]*mag;
vec[3] = 0.0f;
glLightfv(target, GL_POSITION, vec);
vec[0] = _color[0] * _ambientIntensity;
vec[1] = _color[1] * _ambientIntensity;
vec[2] = _color[2] * _ambientIntensity;
vec[3] = 1.0f;
glLightfv(target, GL_AMBIENT, vec);
vec[0] = _color[0] * _intensity;
vec[1] = _color[1] * _intensity;
vec[2] = _color[2] * _intensity;
vec[3] = 1.0f;
glLightfv(target, GL_DIFFUSE, vec);
vec[0] = spec[0] * _intensity;
vec[1] = spec[1] * _intensity;
vec[2] = spec[2] * _intensity;
vec[3] = spec[3];
glLightfv(target, GL_SPECULAR, vec);
GLfloat _cutOffAngle = 180;
glLightfv(target, GL_SPOT_CUTOFF, &_cutOffAngle);
GLfloat _exponent = 0;
glLightfv(target, GL_SPOT_EXPONENT, &_exponent);
GLfloat _attenuation[3] = {1,0,0};
glLightfv(target, GL_CONSTANT_ATTENUATION, &_attenuation[0] );
glLightfv(target, GL_LINEAR_ATTENUATION, &_attenuation[1] );
glLightfv(target, GL_QUADRATIC_ATTENUATION, &_attenuation[2] );
}
void InitGL(GLvoid)
{
wglMakeCurrent(hDC,hRC);
GLboolean val;
glGetBooleanv(GL_INDEX_MODE, &val);
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
if(useLighting) {
glEnable(GL_LIGHTING);
drawLight();
}
wglMakeCurrent(NULL, NULL);
wglMakeCurrent(hDC,hLRC);
glGetBooleanv(GL_INDEX_MODE, &val);
glShadeModel(GL_SMOOTH);
glClearIndex(0);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
if(useLighting) {
glEnable(GL_LIGHTING);
drawLight();
}
wglMakeCurrent(NULL, NULL);
}
int DrawGLScene(GLvoid)
{
static float trans = 0;
static float delta = 0.1f;
// if(trans > 2.0 | | trans < -2.0)
// delta = -delta;
//trans += delta;
trans = -1.2;
wglMakeCurrent(hDC,hRC);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0f,trans,-6.0f);
// double eq[] = {-1.0, 0.0, 0.0};
// glClipPlane(GL_CLIP_PLANE0, eq);
// glEnable(GL_CLIP_PLANE0);
if(useLighting) {
float color[] = {1.0, 0.0, 0.0};
glMaterialfv(GL_FRONT, GL_DIFFUSE, color);
}
else
glColor3f(1.0, 0.0, 0.0);
gluSphere( gluNewQuadric(), 1, 30, 30);
wglMakeCurrent(NULL,NULL);
if(layerMode) {
wglMakeCurrent(hDC,hLRC); // Layer
trans = 1.2;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0f,trans,-6.0f);
// double eq[] = {1.0, 0.0, 0.0};
// glClipPlane(GL_CLIP_PLANE0, eq);
// glEnable(GL_CLIP_PLANE0);
if(layerColorModeIndex) {
if(useLighting) {
GLint indices[3];
indices[0] = 0;//255;//_ambientIndex;
indices[1] = 255;//_diffuseIndex;
indices[2] = 0;//255;//_specularIndex;
glMaterialiv(GL_FRONT, GL_COLOR_INDEXES, indices);
}
else
glIndexi(255);
}
else
glColor3f(0.0f,1.0f,0.0f);
gluSphere( gluNewQuadric(), 1, 30, 30);
wglMakeCurrent(NULL,NULL);
}
return TRUE;
}
BOOL CreateGLWindow(char* title, int width, int height,
int bits, bool fullscreenflag)
{
GLuint PixelFormat;
WNDCLASS wc;
DWORD dwExStyle;
DWORD dwStyle;
RECT WindowRect;
WindowRect.left=(long)0;
WindowRect.right=(long)width;
WindowRect.top=(long)0;
WindowRect.bottom=(long)height;
hInstance = GetModuleHandle(NULL);
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = (WNDPROC) WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = “OpenGL”;
RegisterClass(&wc);
dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
dwStyle=WS_OVERLAPPEDWINDOW;
AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);
// Create The Window
hWnd=CreateWindowEx( dwExStyle,
“OpenGL”,
title,
dwStyle | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
0, 0,
WindowRect.right-WindowRect.left,
WindowRect.bottom-WindowRect.top,
NULL,
NULL,
hInstance,
NULL);
static PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL |
PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
bits,
0, 0, 0, 0, 0, 0,
0,
0,
0,
0, 0, 0, 0,
16,
0,
0,
PFD_MAIN_PLANE,
layerMode ? 1 : 0, // Reserved
0, 0, 0
};
hDC=GetDC(hWnd);
//PixelFormat=ChoosePixelFormat(hDC,&pfd);
PixelFormat = getPF(hDC, &pfd);
SetPixelFormat(hDC,PixelFormat,&pfd);
hRC=wglCreateContext(hDC);
wglMakeCurrent(hDC,hRC);
// Create Layer context
if(layerMode) {
hLRC = wglCreateLayerContext(hDC, 1); //
COLORREF colorMap[256];
wglGetLayerPaletteEntries(hDC, 1, 0, 256, colorMap);
for(int j = 0; j < 256; ++j)
{
colorMap[j] = j << 8;
}
int err = wglSetLayerPaletteEntries(hDC, 1, 0, 256, colorMap);
BOOL r = wglRealizeLayerPalette(hDC, 1, TRUE);
LAYERPLANEDESCRIPTOR lpd;
wglDescribeLayerPlane(hDC, GetPixelFormat(hDC), 1,
sizeof(LAYERPLANEDESCRIPTOR),
&lpd);
if(lpd.iPixelType == PFD_TYPE_RGBA)
layerColorModeIndex = false;//COLORMODE_RGB;
else
layerColorModeIndex = true;//COLORMODE_INDEX;
}
ShowWindow(hWnd,SW_SHOW);
SetForegroundWindow(hWnd);
SetFocus(hWnd);
ReSizeGLScene(width, height);
InitGL();
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_KEYDOWN:
{
keys[wParam] = TRUE;
return 0;
}
case WM_KEYUP:
{
keys[wParam] = FALSE;
return 0;
}
case WM_SIZE:
{
ReSizeGLScene(LOWORD(lParam),HIWORD(lParam));
return 0;
}
}
// Pass All Unhandled Messages To DefWindowProc
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
BOOL done=FALSE;
if (MessageBox(NULL,“Enable lighting?”, “”,MB_YESNO|MB_ICONQUESTION)==IDNO)
{
useLighting = false;
}
// Create Our OpenGL Window
if (!CreateGLWindow(“Overlay test program”,640,480,16,FALSE))
{
return 0;
}
while(!done)
{
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if (msg.message==WM_QUIT)
{
done=TRUE;
}
else
{
TranslateMessage(&msg); // Translate The Message
DispatchMessage(&msg); // Dispatch The Message
}
}
else
{
if ((/*active && */!DrawGLScene()) | | keys[VK_ESCAPE])
{
done=TRUE;
}
else
{
if(layerMode) {
wglSwapLayerBuffers(hDC, WGL_SWAP_MAIN_PLANE | WGL_SWAP_OVERLAY1);
}
else
SwapBuffers(hDC);
}
}
}
return (msg.wParam);
}
int getPF(HDC hDC, const PIXELFORMATDESCRIPTOR *pfd)
{
PIXELFORMATDESCRIPTOR tmpPfd;
unsigned int noOfPixelFormats =
DescribePixelFormat(hDC, 1, sizeof(PIXELFORMATDESCRIPTOR), &tmpPfd);
int *validPixelFormats = new int[noOfPixelFormats];
for(unsigned int i = 0 ; i < noOfPixelFormats; i++) {
validPixelFormats[i] = 1;
}
for(i = 0 ; i < noOfPixelFormats; i++) {
DescribePixelFormat(hDC, i+1, sizeof(PIXELFORMATDESCRIPTOR), &tmpPfd);
// dwFlags
if( (tmpPfd.dwFlags & pfd->dwFlags) ^ pfd->dwFlags )
validPixelFormats[i] = 0; // Not valid.
// iPixelType
if(tmpPfd.iPixelType != pfd->iPixelType)
validPixelFormats[i] = 0; // Not valid.
// cColorBits
if(tmpPfd.cColorBits < pfd->cColorBits)
validPixelFormats[i] = 0; // Not valid.
// cRedBits
if(tmpPfd.cRedBits < pfd->cRedBits)
validPixelFormats[i] = 0; // Not valid.
// cRedShift
if(tmpPfd.cRedShift < pfd->cRedShift)
validPixelFormats[i] = 0; // Not valid.
// cGreenBits
if(tmpPfd.cGreenBits < pfd->cGreenBits)
validPixelFormats[i] = 0; // Not valid.
// cGreenShift
if(tmpPfd.cGreenShift < pfd->cGreenShift)
validPixelFormats[i] = 0; // Not valid.
// cBlueBits
if(tmpPfd.cBlueBits < pfd->cBlueBits)
validPixelFormats[i] = 0; // Not valid.
// cBlueShift
if(tmpPfd.cBlueShift < pfd->cBlueShift)
validPixelFormats[i] = 0; // Not valid.
// cAlphaBits
if(tmpPfd.cAlphaBits < pfd->cAlphaBits)
validPixelFormats[i] = 0; // Not valid.
// cAlphaShift
if(tmpPfd.cAlphaShift < pfd->cAlphaShift)
validPixelFormats[i] = 0; // Not valid.
// cAccumBits
if(tmpPfd.cAccumBits < pfd->cAccumBits)
validPixelFormats[i] = 0; // Not valid.
// cAccumRedBits
if(tmpPfd.cAccumRedBits < pfd->cAccumRedBits)
validPixelFormats[i] = 0; // Not valid.
// cAccumGreenBits
if(tmpPfd.cAccumGreenBits < pfd->cAccumGreenBits)
validPixelFormats[i] = 0; // Not valid.
// cAccumBlueBits
if(tmpPfd.cAccumBlueBits < pfd->cAccumBlueBits)
validPixelFormats[i] = 0; // Not valid.
// cAccumAlphaBits
if(tmpPfd.cAccumAlphaBits < pfd->cAccumAlphaBits)
validPixelFormats[i] = 0; // Not valid.
// cDepthBits
if(tmpPfd.cDepthBits < pfd->cDepthBits)
validPixelFormats[i] = 0; // Not valid.
// cStencilBits
if(tmpPfd.cStencilBits < pfd->cStencilBits)
validPixelFormats[i] = 0; // Not valid.
// cAuxBuffers
if(tmpPfd.cAuxBuffers < pfd->cAuxBuffers)
validPixelFormats[i] = 0; // Not valid.
// iLayerType is no longer used.
// bReserved. // overlay and underlay planes
BYTE overlaysSupported = (tmpPfd.bReserved & 7);
BYTE overlaysWanted = (pfd->bReserved & 7);
BYTE underlaysSupported = (tmpPfd.bReserved > 3);
BYTE underlaysWanted = (pfd->bReserved > 3);
if( (overlaysSupported < overlaysWanted) | |
(underlaysSupported < underlaysWanted))
validPixelFormats[i] = 0; // Not valid.
// dwLayerMask is no longer used.
// dwVisibleMask ??
// dwDamageMask is no longer used.
}
// How many left?
int firstValid = -1;
for(i = 0 ; i < noOfPixelFormats; i++) {
if(validPixelFormats[i]) {
if(firstValid == -1)
firstValid = i+1;
}
}
return firstValid;
}