[Solved] Variable substitute for GL_LIGHT0, GL_LIGHT 1, etc.
Is there a way to substitute a variable for GL_LIGHT0, GL_LIGHT1, GL_LIGHT2, etc. When you are using the glLightfv call. For example, if I have a series of lights, how can I change it so that I can just loop through the lights and call glLightfv for whatever number light I am at?
[Edited by - Eddy999999 on October 15, 2006 3:14:31 PM]
GL_LIGHTn values are guaranteed contiguous; so you can do something like:
for(int i = 0; i < /* number of lights */; ++i){ glSomethingOrOther(GL_LIGHT0 + i,...);}
Hmm, I'm not getting any errors when I compile, but when I run the application, it crashes. I get a message from ZoneAlarm saying that lesson10.exe (the name of my app) is tryint to launch C:\WINDOWS\system32\dwwin.exe, and if I want to allow it to. I don't know what dwwin.exe is, and I have neer seen it before. Here's my code:
I tried doing some debugging, and I founf that when I commented out the following code, the app didn't crash:
Which is weird, because I've never had any problems with lighting in the past.
//First, we need to include the required header files#include <windows.h> //Windows header file#include <math.h> //Math header file#include <stdio.h> //Standard file input/output header file#include <gl/gl.h> // - - v#include <gl/glu.h> // - - > OpenGL Header Files#include <gl/glaux.h> // - - ^HGLRC hRC = NULL; //Rendering ContextHDC hDC = NULL; //Device ContextHWND hWnd = NULL; //Window HandleHINSTANCE hInstance = NULL; //Window Instancebool keys[256]; //Array used for keys which are pressedbool active = true; //Whether or not the window is activebool fullscreen = true; //Whether or not the program is in full screenbool lp; //L pressedbool lighting; //Lighting activated/deactivatedconst float piover180 = 0.0174532925f;float heading;float xpos, zpos;GLfloat LightAmbient[]= { 0.5f, 0.5f, 0.5f, 1.0f };GLfloat yrot;GLfloat walkbias=0;GLfloat walkbiasangle=0;GLfloat lookupdown=0.0f;GLfloat z=0.0f;GLuint filter;GLuint texture[3];typedef struct tagVERTEX{ float x, y, z; float u, v;} VERTEX;typedef struct tagPOLY{ int numvertices; VERTEX* vertex;} POLY;typedef struct tagLIGHT{ GLfloat LightPosition[4]; GLfloat LightDiffuse[4];} LIGHT;typedef struct tagSECTOR{ int numpollies; POLY* poly; int numlights; LIGHT* light;} SECTOR;SECTOR sector1;LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); //WndProc prototypevoid readstr(FILE *f, char *string){ do { fgets(string, 255, f); } while ((string[0] == '/') || (string[0] == '\n')); return;}void SetupWorld(){ float x, y, z, u, v; int numpollies; int numlights;; FILE *filein; char oneline[255]; filein = fopen("data/world.txt", "rt"); readstr(filein,oneline); sscanf(oneline, "NUMPOLLIES %d\n", &numpollies); sector1.poly = new POLY[numpollies]; sector1.numpollies = numpollies; for (int loop = 0; loop < numpollies; loop++) { readstr(filein, oneline); if (oneline[0]=='Q') { sector1.poly[loop].numvertices=4; } else { sector1.poly[loop].numvertices=3; } sector1.poly[loop].vertex=new VERTEX[sector1.poly[loop].numvertices]; for (int vert = 0; vert < sector1.poly[loop].numvertices; vert++) { readstr(filein,oneline); sscanf(oneline, "%f %f %f %f %f", &x, &y, &z, &u, &v); sector1.poly[loop].vertex[vert].x = x; sector1.poly[loop].vertex[vert].y = y; sector1.poly[loop].vertex[vert].z = z; sector1.poly[loop].vertex[vert].u = u; sector1.poly[loop].vertex[vert].v = v; } } readstr(filein, oneline); sscanf(oneline, "NUMLIGHTS %d\n", &numlights); sector1.light=new LIGHT[numlights]; sector1.numlights=numlights; for (loop=0; loop < numlights; loop++) { readstr(filein, oneline); sscanf(oneline, "%f, %f, %f, %f", &x, &y, &z, &u); static GLfloat LightDiffuse [] = {x, y, z, u}; for (int loop2; loop2<4; loop2++) { sector1.light[loop].LightDiffuse[loop2]=LightDiffuse[loop2]; } readstr(filein, oneline); sscanf(oneline, "%f, %f, %f, %f", &x, &y, &z, &u); static GLfloat LightPosition [] = {x, y, z, u}; for (loop2; loop2<4; loop2++) { sector1.light[loop].LightPosition[loop2]=LightPosition[loop2]; } } fclose(filein); return;}AUX_RGBImageRec *LoadBMP(char *Filename) //Loads a BMP{ FILE *File=NULL; if (!Filename) { return NULL; } File=fopen(Filename,"r"); if (File) { fclose(File); return auxDIBImageLoad(Filename); } return NULL;}int LoadGLTextures() // Load Bitmaps And Convert To Textures{ int Status=FALSE; // Status Indicator AUX_RGBImageRec *TextureImage[1]; // Create Storage Space For The Texture memset(TextureImage,0,sizeof(void *)*1); if (TextureImage[0]=LoadBMP("Data/Metal.bmp")) { Status=true; glGenTextures(3, &texture[0]); glBindTexture(GL_TEXTURE_2D, texture[0]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); } if (TextureImage[0]) { if (TextureImage[0]->data) { free(TextureImage[0]->data); } free(TextureImage[0]); } return Status;}GLvoid ReSizeGLScene(GLsizei width, GLsizei height) //Resizes and initializes the OpenGL Window{ if (height==0) { height=1; //Prevents a divide by zero } glViewport(0, 0, width, height); //Resets the current viewport glMatrixMode(GL_PROJECTION); //Select the projection matrix glLoadIdentity(); //Reset the projection matrix gluPerspective(45.0f, (GLfloat)width/(GLfloat)height, 0.1f, 100.0f); //Calculates the aspect ratio of the window glMatrixMode(GL_MODELVIEW); //Select the modelview matrix glLoadIdentity(); //Reset the modelview matrix}int InitGL(GLvoid) //Setup for OpenGL{ if (!LoadGLTextures()) // Jump To Texture Loading Routine { return FALSE; // If Texture Didn't Load Return FALSE } glEnable(GL_TEXTURE_2D); glBlendFunc(GL_SRC_ALPHA,GL_ONE); glShadeModel(GL_SMOOTH); //Enables smooth shading glClearColor(0.0f, 0.0f, 0.0f, 0.0f); //Black background glClearDepth(1.0f); //Depth buffer setup glEnable(GL_DEPTH_TEST); //Enables depth testing glDepthFunc(GL_LEQUAL); //Type of depth test to do glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); //Good perception calculations SetupWorld(); for (int loop=0; loop<sector1.numlights; loop++) { glLightfv(GL_LIGHT0+loop, GL_AMBIENT, LightAmbient); //Set up the ambient light glLightfv(GL_LIGHT0+loop, GL_DIFFUSE, sector1.light[loop].LightDiffuse); //Set up the diffuse light glLightfv(GL_LIGHT0+loop, GL_POSITION,sector1.light[loop].LightPosition); //Position the light glEnable(GL_LIGHT0+loop); } return true;}int DrawGLScene(GLvoid) // Here's Where We Do All The Drawing{ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); GLfloat x_m, y_m, z_m, u_m, v_m; GLfloat xtrans=-xpos; GLfloat ztrans=-zpos; GLfloat ytrans=-walkbias-0.25f; GLfloat sceneroty=360.0f-yrot; int numpollies; glRotatef(lookupdown, 1.0f, 0, 0); glRotatef(sceneroty, 0, 1.0f, 0); glTranslatef(xtrans, ytrans, ztrans); glBindTexture(GL_TEXTURE_2D, texture[filter]); numpollies=sector1.numpollies; for (int loop_m = 0; loop_m < numpollies; loop_m++) { if (sector1.poly[loop_m].numvertices==3) { glBegin(GL_TRIANGLES); } else { glBegin(GL_QUADS); } glNormal3f(0.0f, 0.0f, 1.0f); for (int loop_m2 = 0; loop_m2<sector1.poly[loop_m].numvertices; loop_m2++) { x_m=sector1.poly[loop_m].vertex[loop_m2].x; y_m=sector1.poly[loop_m].vertex[loop_m2].y; z_m=sector1.poly[loop_m].vertex[loop_m2].z; u_m=sector1.poly[loop_m].vertex[loop_m2].u; v_m=sector1.poly[loop_m].vertex[loop_m2].v; glTexCoord2f(u_m, v_m); glVertex3f(x_m, y_m, z_m); } glEnd(); } return true;}GLvoid KillGLWindow(GLvoid) //Kills the window properly{ if (fullscreen) //If we are in fullscreen mode { ChangeDisplaySettings(NULL, 0); //then switch back to desktop ShowCursor(true); //and display the cursor } if (hRC) //If we have a rendering context { if (!wglMakeCurrent(NULL, NULL)) //Release the DC and RC contexts { MessageBox(NULL, "Release of DC and RC failed.", "Shutdown Error", MB_OK | MB_ICONINFORMATION); } if (!wglDeleteContext(hRC)) //Delete the RC { MessageBox(NULL, "Release Render Conext Failed.", "Shutdown Error", MB_OK | MB_ICONINFORMATION); } hRC=NULL; //Set RC to NULL } if (hDC && !ReleaseDC(hWnd,hDC)) //Release the DC { MessageBox(NULL, "Release Device Context Failed.", "Shutdown Error", MB_OK | MB_ICONINFORMATION); hDC=NULL; } if (hWnd && !DestroyWindow(hWnd)) //Destroy the window { MessageBox(NULL, "Could not release hWnd.", "Shutdown Error", MB_OK | MB_ICONINFORMATION); hWnd=NULL; } if (!UnregisterClass("OpenGL", hInstance)) //Unregister the class { MessageBox(NULL, "Could not unregister class.", "Shutdown Error", MB_OK | MB_ICONINFORMATION); hInstance=NULL; }}bool CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag) //Create the OpenGL window{ GLuint PixelFormat; //Holds the result after searching for a match WNDCLASS wc; //Windows class structure DWORD dwExStyle; //Window Extended Style DWORD dwStyle; //Window Style RECT WindowRect; //Holds upper-left and lower-right values of the window WindowRect.left=(long)0; //Left is zero WindowRect.right=(long)width; //Right is the width WindowRect.top=(long)0; //Top is 0 WindowRect.bottom=(long)height; //Bottom is the height fullscreen=fullscreenflag; //Fullscreen is as requested hInstance=GetModuleHandle(NULL); //Gets an instance for the window //Declares the window class wc.style=CS_HREDRAW | CS_VREDRAW | CS_OWNDC; //Redraw when moved, and own DC wc.lpfnWndProc=(WNDPROC)WndProc; //WndProc function handles messages wc.cbClsExtra=0; //Extra window data wc.cbWndExtra=0; //Extra window data wc.hInstance=hInstance; //Set the instance wc.hIcon=LoadIcon(NULL, IDI_WINLOGO); //Set the icon wc.hCursor=LoadCursor(NULL, IDC_ARROW); //Set the cursor wc.hbrBackground=NULL; //Set the background wc.lpszMenuName=NULL; //Set the menu wc.lpszClassName="OpenGL"; //Set the name of the class if (!RegisterClass(&wc)) //Registers the class defined above { MessageBox(NULL, "Failed to register the window class.", "ERROR", MB_OK | MB_ICONEXCLAMATION); return false; } if (fullscreen) //If we are in fullscreen mode { DEVMODE dmScreenSettings; //Device mode memset(&dmScreenSettings, 0, sizeof(dmScreenSettings)); //Make sure the memory's cleared dmScreenSettings.dmSize=sizeof(dmScreenSettings); //Size of the device mode structure dmScreenSettings.dmPelsWidth=width; //Screen width dmScreenSettings.dmPelsHeight=height; //Screen height dmScreenSettings.dmBitsPerPel=bits; //Bits per pixel dmScreenSettings.dmFields=DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) //Changes the display settings { if (MessageBox(NULL, "The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?", "NeHe GL", MB_YESNO | MB_ICONEXCLAMATION)==IDYES) //Asks if the user would like to switch to windowed mode { fullscreen=false; } else { MessageBox(NULL, "The Program Will Now Quit.", "ERROR", MB_OK | MB_ICONSTOP); return false; } } } if (fullscreen) { dwExStyle=WS_EX_APPWINDOW; //Window extended style dwStyle=WS_POPUP; //Window style - WS_POPUP gets rid of all borders around a window ShowCursor(false); //Hide the cursor } else { dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; //Window extended style dwStyle=WS_OVERLAPPEDWINDOW; //Window style - WS_OVERLAPPEDWINDOW gives the window a title bar, sizing border, window menu, and min/max buttons } AdjustWindowRectEx(&WindowRect, dwStyle, false, dwExStyle); //Adjust the window to true requested sizes //Create the window: if (!(hWnd=CreateWindowEx( dwExStyle, //Window extended style "OpenGL", //Window class name, as defined above title, //Title of the window WS_CLIPSIBLINGS | //Required WS_CLIPCHILDREN | //Required dwStyle, //Window style 0,0, //Window coordinates WindowRect.right-WindowRect.left, //Window width WindowRect.bottom-WindowRect.top, //Windot height NULL, //Parent window NULL, //Menu hInstance, //Instance NULL))) //Passed to WM_CREATE { KillGLWindow(); //Destroys the window if window creation fials MessageBox(NULL, "Window Creation Error.", "ERROR", MB_OK | MB_ICONEXCLAMATION); return false; } static PIXELFORMATDESCRIPTOR pfd= //Tells windows how we want things to be { sizeof(PIXELFORMATDESCRIPTOR), //Size of Pixel Format Descriptor 1, //Version number PFD_DRAW_TO_WINDOW | //Must support window PFD_SUPPORT_OPENGL | //Must support OpenGL PFD_DOUBLEBUFFER, //Must support double buffering PFD_TYPE_RGBA, //RGBA format bits, //Color depth 0, 0, 0, 0, 0, 0, //Color bits 0, //Alpha buffer 0, //Shift bit 0, //Accumulation buffer 0, 0, 0, 0, //Accumulation bits 16, //16-bit Z-Buffer 0, //Stencil buffer 0, //Auxiliary buffer PFD_MAIN_PLANE, //Main drawing layer 0, //Reserved 0, 0, 0 //Layer masks }; if (!(hDC=GetDC(hWnd))) //Get a device context { KillGLWindow(); MessageBox(NULL, "Can't Create A GL Device Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION); return false; } if (!(PixelFormat=ChoosePixelFormat(hDC, &pfd))) //Find a matching pixel format { KillGLWindow(); MessageBox(NULL, "Can't Find A Suitable PixelFormat.", "ERROR", MB_OK | MB_ICONEXCLAMATION); return false; } if (!SetPixelFormat(hDC, PixelFormat, &pfd)) //Set the pixel format { KillGLWindow(); MessageBox(NULL, "Can't Set The PixelFormat.", "ERROR", MB_OK | MB_ICONEXCLAMATION); return false; } if (!(hRC=wglCreateContext(hDC))) //Get a rendering context { KillGLWindow(); MessageBox(NULL, "Can't Create A GL Rendering Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION); return false; } if (!wglMakeCurrent(hDC, hRC)) //Activate the rendering context { KillGLWindow(); MessageBox(NULL, "Can't Activate the GL Rendering Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION); return false; } ShowWindow(hWnd, SW_SHOW); //Show the window SetForegroundWindow(hWnd); //Give the window slightly higher priority SetFocus(hWnd); //Set the focus to the window ReSizeGLScene(width, height); //Set up our perspective if (!InitGL()) //Initialize our new GL window { KillGLWindow(); MessageBox(NULL, "Initialization Failed.", "ERROR", MB_OK | MB_ICONEXCLAMATION); return false; } return true;}//Handles windows messages:LRESULT CALLBACK WndProc( HWND hWnd, //Window handle UINT uMsg, //Message WPARAM wParam, //Additional message info LPARAM lParam) //Additional message info{ switch (uMsg) //Check the message { case WM_ACTIVATE: //The window has been activated/deactivated { if (!HIWORD(wParam)) { active=true; } else { active=false; } return 0; } case WM_SYSCOMMAND: //Windows is trying to start the screens saver, or power down the moniter { switch (wParam) { case SC_SCREENSAVE: case SC_MONITORPOWER: return 0; //Don't let the screensaver start, or the moniter power down } break; } case WM_CLOSE: //The window is closing { PostQuitMessage(0); return 0; } case WM_KEYDOWN: //A key on the keyboard is down { keys[wParam]=true; return 0; } case WM_KEYUP: //A key on the keyboard has been released { keys[wParam]=false; return 0; } case WM_SIZE: //The window has been resized { ReSizeGLScene(LOWORD(lParam), HIWORD(lParam)); return 0; } } return DefWindowProc(hWnd, uMsg, wParam, lParam);}int WINAPI WinMain( HINSTANCE hInstance, //Instance of the window HINSTANCE hPrevInstance, //Previous instance of the window LPSTR lpCmdLine, //command line parameters int nCmdShow) //Window show state{ MSG msg; //Windows message structure bool done=false; //Variable to exit loop //Asks the user if they would like to run in fullscreen mode if (MessageBox(NULL, "Would You Like To Run In Fullscreen Mode?", "Start Fullscreen?", MB_YESNO | MB_ICONQUESTION)==IDNO) { fullscreen=false; } if (!CreateGLWindow("Lionel Brits & NeHe's 3D World Tutorial", 640, 480, 16, fullscreen)) //Create the window { return 0; } //Main loop while (!done) { if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) //Checks for messages { if (msg.message==WM_QUIT) //The program is closing { done=true; } else { TranslateMessage(&msg); //Translate the message DispatchMessage(&msg); //Dispatch the message } } else { if (active) { if (keys[VK_ESCAPE]) //If the escape key was pressed { done=true; //Allow the loop to end } else { DrawGLScene(); SwapBuffers(hDC); if (keys[VK_RIGHT]) { heading-=1.0f; yrot=heading; } if (keys[VK_LEFT]) { heading+=1.0f; yrot=heading; } if (keys[VK_UP]) { xpos-=(float)sin(heading*piover180)*0.05f; zpos-=(float)cos(heading*piover180)*0.05f; if (walkbiasangle>=359.0f) { walkbiasangle=0.0f; } else { walkbiasangle+=10; } walkbias=(float)sin(walkbiasangle*piover180)/20.0f; } if (keys[VK_DOWN]) { xpos+=(float)sin(heading*piover180)*0.05f; zpos+=(float)cos(heading*piover180)*0.05f; if (walkbiasangle<1.0f) { walkbiasangle=359.0f; } else { walkbiasangle-=10; } walkbias=(float)sin(walkbiasangle*piover180)*0.05f; } if (keys['L'] && !lp) { lp=true; lighting=!lighting; if (!lighting) { glDisable(GL_LIGHTING); } else { glEnable(GL_LIGHTING); } } if (!keys['L']) { lp=false; } } } if (keys[VK_F1]) //If the F1 key was pressed, then switch between windowed mode and fullscreen mode { keys[VK_F1]=false; KillGLWindow(); fullscreen=!fullscreen; if (!CreateGLWindow("Lionel Brits & NeHe's 3D World Tutorial", 640, 480, 16, fullscreen)) { return 0; } } } } KillGLWindow(); //Kill the window return (msg.wParam);}
I tried doing some debugging, and I founf that when I commented out the following code, the app didn't crash:
for (int loop=0; loop<sector1.numlights; loop++){ glLightfv(GL_LIGHT0+loop, GL_AMBIENT, LightAmbient); //Set up the ambient light glLightfv(GL_LIGHT0+loop, GL_DIFFUSE, sector1.light[loop].LightDiffuse); //Set up the diffuse light glLightfv(GL_LIGHT0+loop, GL_POSITION,sector1.light[loop].LightPosition); //Position the light glEnable(GL_LIGHT0+loop);}
Which is weird, because I've never had any problems with lighting in the past.
OK, do you have any idea of what scausing it, or how to solve it? Is it just because of an error in my code?
Check your loop variables. loop2 is not initialized to 0.
If debug works and release doesn't that would be one cause.
You can also start a release build of your program in the debugger and see if it points to the crash.
Be aware thet GL_MAX_LIGHTS is an implementation dependent constant and 8 lights are granted by OpenGL. Some implementations offered more, but that's rather irrelevant with programmable pipelines today.
Aside from that, I would put the glNormal call outside the glBegin-glEnd if it is constant for the whole primitive, but I wouldn't use immediate mode but vertex arrays in vertex buffer objects.
If debug works and release doesn't that would be one cause.
You can also start a release build of your program in the debugger and see if it points to the crash.
Be aware thet GL_MAX_LIGHTS is an implementation dependent constant and 8 lights are granted by OpenGL. Some implementations offered more, but that's rather irrelevant with programmable pipelines today.
Aside from that, I would put the glNormal call outside the glBegin-glEnd if it is constant for the whole primitive, but I wouldn't use immediate mode but vertex arrays in vertex buffer objects.
Thanks, I initialized the loops to 0, and it doesn't crash anymore.
However, when I press L to turn on lighting, I get a black screen. Did I forget something?
Thanks a ton for the help so far by the way! :D
However, when I press L to turn on lighting, I get a black screen. Did I forget something?
Thanks a ton for the help so far by the way! :D
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement