[Solved] Variable substitute for GL_LIGHT0, GL_LIGHT 1, etc.

Started by
8 comments, last by Eddy999999 17 years, 6 months ago
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]
God is not all-powerful, as he cannot build a wall he cannot jump.Stelimar Website: eddy999999.ed.funpic.org/Stelimar/index.html
Advertisement
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,...);}
Thanks, I'll try that out. Is GL_LIGHT0, GL_LIGHT1, etc. just a series of constants?
God is not all-powerful, as he cannot build a wall he cannot jump.Stelimar Website: eddy999999.ed.funpic.org/Stelimar/index.html
Yep they are, look in gl.h and see for yourself.
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:

//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.
God is not all-powerful, as he cannot build a wall he cannot jump.Stelimar Website: eddy999999.ed.funpic.org/Stelimar/index.html
dwwin.exe is Dr. Watson, part of the windows error reporting tool.
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?
God is not all-powerful, as he cannot build a wall he cannot jump.Stelimar Website: eddy999999.ed.funpic.org/Stelimar/index.html
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.
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
God is not all-powerful, as he cannot build a wall he cannot jump.Stelimar Website: eddy999999.ed.funpic.org/Stelimar/index.html
K, I figured it out. I had to change
sscanf(oneline, "%f, %f, %f, %f", &x, &y, &z, &u);

to
sscanf(oneline, "%f %f %f %f", &x, &y, &z, &u);

(I accidentally put in comas :P)
God is not all-powerful, as he cannot build a wall he cannot jump.Stelimar Website: eddy999999.ed.funpic.org/Stelimar/index.html

This topic is closed to new replies.

Advertisement