Multitexturing with lighting

Dear me, two threads so close together…ah well.

My problem this time is lighting. I have a terrain with multitexturing, and it looks very nice :slight_smile: the problem is when i turn on lighting things go all odd. I have code to calculate the normals of each quad which works fine, but for some reason things go all brown :stuck_out_tongue: Here’s some images:
Lit:

Unlit:

can you post your light setup code? Lots of things can hose lighting.

Light setup:

 
GLfloat Light_Ambient1[] = {0.5f, 0.5f, 0.5f, 1.0f};  //RGBA of ambient light
GLfloat Light_Diffuse1[] = {0.0f, 0.0f, 0.0f, 1.0f};  //RGBA of light scattered after impact
GLfloat Light_Position1[]= {0.0f, 25.0f, 0.0f, 1.0f}; //Position of light source
GLfloat Light_Specular1[]= {0.0f, 0.0f, 0.0f, 1.0f};  //RGBA of bounced beam

GLfloat Light_Ambient2[] = {0.5f, 0.5f, 0.5f, 1.0f};  //RGBA of ambient light
GLfloat Light_Diffuse2[] = {0.0f, 0.0f, 0.0f, 1.0f};  //RGBA of light scattered after impact
GLfloat Light_Position2[]= {25.0f, 25.0f, 37.0f, 1.0f}; //Position of light source
GLfloat Light_Specular2[]= {0.0f, 0.0f, 0.0f, 1.0f};  //RGBA of bounced beam


	glLightfv(GL_LIGHT1, GL_AMBIENT,  Light_Ambient1);
	glLightfv(GL_LIGHT1, GL_DIFFUSE,  Light_Diffuse1);
	glLightfv(GL_LIGHT1, GL_POSITION, Light_Position1);
	glLightfv(GL_LIGHT1, GL_SPECULAR, Light_Specular1);
	glEnable(GL_LIGHT1);							// Enable Light One

	glLightfv(GL_LIGHT2, GL_AMBIENT,  Light_Ambient2);
	glLightfv(GL_LIGHT2, GL_DIFFUSE,  Light_Diffuse2);
	glLightfv(GL_LIGHT2, GL_POSITION, Light_Position2);
	glLightfv(GL_LIGHT2, GL_SPECULAR, Light_Specular2);
	glEnable(GL_LIGHT2);							// Enable Light One
 

Draw Code:

void DrawScene() 
{	
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	// Clear Screen And Depth Buffer
	glLoadIdentity();									// Reset The Current Modelview Matrix
	
	float sy = sin(yaw);
	float cy = cos(yaw);
	float sp = sin(pitch);
	float cp = cos(pitch);

				WWLA[0] = WWA[0] + sy * cp;
				WWLA[1] = WWA[1] - sp;
				WWLA[2] = WWA[2] + cy * cp;

gluLookAt(
    WWA[0],				//Where we're at
    WWA[1],
    WWA[2],
    WWLA[0],	//Where we're looking at (based on where we're at)
    WWLA[1],
    WWLA[2],
    0,					//Which direction is up
    1,
    0
);


	GetTileHeight(User->position[0], User->position[2]);
	DrawModels();
	glTranslatef(0.0f, 0.0f, 0.0f);
 	RenderHeightMap(g_HeightMap);						// Render The Height Map

//	glAccum(GL_MULT,0.5f); 
//	glAccum(GL_ACCUM,1.0f); 
//	glAccum(GL_RETURN ,1.0f); 

	SwapBuffers(ghdc);// Swap the frame buffers.

//CheckMouse();	//Check for mouse input
	glFlush();

}

Your lights are both local light sources, you probably want to set the 4th coord to 0 to make it a distant vector light and ensure brighter illumination without local position/attenuations issues.

P.S. position the light only when the appropriate matrix is on the modelview stack, for example if your light is positioned relative to the world then position it when your viewing matrix and only your viewing matrix is on the modelview.

Did you set material properties correctly?

By the way - have you considered using lightmap instead of realtime lighting? I always used this approach for terrain - soft shadows at no cost;)

Ok I haven’t used materials, and this may be the reason it doesn’t work. I then went and tried to use materials, but i just end up with darkness :stuck_out_tongue:

GLfloat no_mat[] = {0.0f, 0.0f, 0.0f, 1.0f};
GLfloat mat_ambient[] = {0.7f, 0.7f, 0.7f, 1.0f};
GLfloat mat_ambient_color[] = {0.8f, 0.8f, 0.2f, 1.0f};
GLfloat mat_diffuse[] = {0.1f, 0.5f, 0.8f, 1.0f};
GLfloat mat_specular[] = {1.0f, 1.0f, 1.0f, 1.0f};
GLfloat no_shininess = 0.0f;
GLfloat low_shininess = 5.0f;
GLfloat high_shininess = 100.0f;
GLfloat mat_emission[] = {0.3f, 0.2f, 0.2f, 0.0f};


void RenderHeightMap(BYTE pHeightMap[])			// This Renders The Height Map As Quads
{
	int X = 0, Y = 0;							// Create Some Variables To Walk The Array With.
	int x, y, z;								// Create Some Variables For Readability
	int i;										// Counter
	char buffer[200];
	int height[4];								//Y value of the 4 vertices making up each quad

	if(!pHeightMap) return;						// Make Sure Our Height Data Is Valid
	float pointCoords[4][3];					//The xyz of the points outlining the quad
	float normal[3];

//////////////////////////////////////////////
///First Pass - Render whole world in grass(!)
//////////////////////////////////////////////

glDisable(GL_BLEND);  //Disable blending

	for ( X = 0; X < (MAP_SIZE-STEP_SIZE); X += STEP_SIZE )
	{
		for ( Y = 0; Y < (MAP_SIZE-STEP_SIZE); Y += STEP_SIZE )
		{	
			height[0] = Height(pHeightMap, X, Y );
			height[1] = Height(pHeightMap, X, Y + STEP_SIZE );  
			height[2] = Height(pHeightMap, X + STEP_SIZE, Y + STEP_SIZE ); 
			height[3] = Height(pHeightMap, X + STEP_SIZE, Y );
		
		glBindTexture(GL_TEXTURE_2D, terrain[1].texture);  //Bind the grass texture
		


		// Get The (X, Y, Z) Value For The Bottom Left Vertex
		pointCoords[0][0] = X;
		pointCoords[0][1] = Height(pHeightMap, X, Y );
		pointCoords[0][2] = Y;
		//Top Left
		pointCoords[1][0]= X;										
		pointCoords[1][1] = Height(pHeightMap, X, Y + STEP_SIZE );  
		pointCoords[1][2]= Y + STEP_SIZE;
		//Top Right
		pointCoords[2][0] = X + STEP_SIZE; 
		pointCoords[2][1] = Height(pHeightMap, X + STEP_SIZE, Y + STEP_SIZE ); 
		pointCoords[2][2] = Y + STEP_SIZE;
		//Bottom Right
		pointCoords[3][0] = X + STEP_SIZE; 
		pointCoords[3][1] = Height(pHeightMap, X + STEP_SIZE, Y ); 
		pointCoords[3][2] = Y;

		FindNormal(pointCoords[0][0], pointCoords[0][1], pointCoords[0][2], 
		pointCoords[1][0], pointCoords[1][1], pointCoords[1][2], 
		pointCoords[2][0], pointCoords[2][1], pointCoords[2][2], normal);

	/*	sprintf(buffer, "Normal:
 %f
%f
%f", normal[0], normal[1], normal[2]);
		MessageBox(NULL, buffer, "normal", MB_OK);*/

		if(bRender)											// What We Want To Render (if polygon mode)
		glBegin( GL_QUADS );								// Render Polygons
		else 
		glBegin( GL_LINES );								// Render Lines Instead (grid, no filler)
					


        glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat);
        glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
        glMaterialfv(GL_FRONT, GL_SPECULAR, no_mat);
        glMaterialf(GL_FRONT, GL_SHININESS, no_shininess);
        glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);


			glNormal3f(normal[0], normal[1], normal[2]);
			glTexCoord2f(0,0); 
			glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
			glVertex3f(pointCoords[0][0],pointCoords[0][1],	pointCoords[0][2]);	 
						
			glNormal3f(normal[0], normal[1], normal[2]);
			glTexCoord2f(1,0); 
			glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
			glVertex3f(pointCoords[1][0],pointCoords[1][1],	pointCoords[1][2]);	 

			glNormal3f(normal[0], normal[1], normal[2]);
			glTexCoord2f(1,1); 
			glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
			glVertex3f(pointCoords[2][0],pointCoords[2][1],	pointCoords[2][2]);	 
	
			glNormal3f(normal[0], normal[1], normal[2]);
			glTexCoord2f(0,1); 
			glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
			glVertex3f(pointCoords[3][0],pointCoords[3][1],	pointCoords[3][2]);	 	
		glEnd();
		}
	}		//end of For x



///////////////////
///////Second Pass
///////Blend the rock texture with the grass to create "gradual rockification"
///////////////////

glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);	
glEnable(GL_BLEND);			//Enable blending
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);		//Our method of blendation

	for ( X = 0; X < (MAP_SIZE-STEP_SIZE); X += STEP_SIZE )
	{
		for ( Y = 0; Y < (MAP_SIZE-STEP_SIZE); Y += STEP_SIZE )
		{	
			height[0] = Height(pHeightMap, X, Y );
			height[1] = Height(pHeightMap, X, Y + STEP_SIZE );  
			height[2] = Height(pHeightMap, X + STEP_SIZE, Y + STEP_SIZE ); 
			height[3] = Height(pHeightMap, X + STEP_SIZE, Y );
		
		glBindTexture(GL_TEXTURE_2D, terrain[2].texture);

		pointCoords[0][0] = X;
		pointCoords[0][1] = Height(pHeightMap, X, Y );
		pointCoords[0][2] = Y;
		//Top Left
		pointCoords[1][0]= X;										
		pointCoords[1][1] = Height(pHeightMap, X, Y + STEP_SIZE );  
		pointCoords[1][2]= Y + STEP_SIZE;
		//Top Right
		pointCoords[2][0] = X + STEP_SIZE; 
		pointCoords[2][1] = Height(pHeightMap, X + STEP_SIZE, Y + STEP_SIZE ); 
		pointCoords[2][2] = Y + STEP_SIZE;
		//Bottom Right
		pointCoords[3][0] = X + STEP_SIZE; 
		pointCoords[3][1] = Height(pHeightMap, X + STEP_SIZE, Y ); 
		pointCoords[3][2] = Y;
			
		FindNormal(pointCoords[0][0], pointCoords[0][1], pointCoords[0][2], 
		pointCoords[1][0], pointCoords[1][1], pointCoords[1][2], 
		pointCoords[2][0], pointCoords[2][1], pointCoords[2][2], normal);

		if(bRender)							// What We Want To Render (if polygon mode)
		glBegin( GL_QUADS );				// Render Polygons
		else 
		glBegin( GL_LINES );				// Render Lines Instead (grid, no filler :D )
	
		

        glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat);
        glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
        glMaterialfv(GL_FRONT, GL_SPECULAR, no_mat);
        glMaterialf(GL_FRONT, GL_SHININESS, no_shininess);
        glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);


			glNormal3f(normal[0], normal[1], normal[2]);
			glTexCoord2f(0,0); 
			glColor4f(1.0f, 1.0f, 1.0f, SetAlpha(Height(pHeightMap, X, Y )));
			glVertex3f(pointCoords[0][0],pointCoords[0][1],	pointCoords[0][2]);	 
			
			glNormal3f(normal[0], normal[1], normal[2]);
			glTexCoord2f(1,0); 
			glColor4f(1.0f, 1.0f, 1.0f, SetAlpha(Height(pHeightMap, X, Y + STEP_SIZE )));
			glVertex3f(pointCoords[1][0],pointCoords[1][1],	pointCoords[1][2]);	 

			glNormal3f(normal[0], normal[1], normal[2]);
			glTexCoord2f(1,1); 
			glColor4f(1.0f, 1.0f, 1.0f, SetAlpha(Height(pHeightMap, X, Y + STEP_SIZE )));
			glVertex3f(pointCoords[2][0],pointCoords[2][1],	pointCoords[2][2]);	 

			glNormal3f(normal[0], normal[1], normal[2]);
			glTexCoord2f(0,1); 
			glColor4f(1.0f, 1.0f, 1.0f, SetAlpha(Height(pHeightMap, X, Y + STEP_SIZE )));
			glVertex3f(pointCoords[3][0],pointCoords[3][1],	pointCoords[3][2]);	 
	
		glEnd();
		}
	}		//end of For x
	
///////////////
///Third pass can come here
///////////////

	glDisable(GL_BLEND);		//No more blending
	glBindTexture(GL_TEXTURE_2D, NULL);					// Clear the bound texture (for prosterity)
}

Try to see Nehe’s tuts.

Originally posted by jide:
Try to see Nehe’s tuts.
is there one concerning materials? I did look but none of them mention materials (that I could see), not even as an aside.

Well, commonly we always use materials when using lighting. Another solution is to use ‘color-material’ but didn’t used it thought.

The code you gave cannot help us because there’s nothing about your lights. How do you create them ? Where do you call the light functions ? This is so important when doing lighting.

Finally, I’d like to advise you to try to do some simple tests first, without blending, texturing and so. Just for ensuring you understand lighting points.

I have done some experimenting with the terrain. Here’s the last picture i think could be of any use…

so could it just be my materials not being set up correctly? its about the only thing that comes to mind :stuck_out_tongue: oddly enough when i look at the floor the screen gets darker…like light isn’t bouncing off the ground?

EDIT: Changed the ambience of the material and the darkness isn’t a problem now. though materials just leave us at the same place:

oddly enough when i look at the floor the screen gets darker…like light isn’t bouncing off the ground?
:smiley:

don’t you think you’ve had enough of that cough syrup, or whatever it is you’re drinking?

why don’t you try again later… after a cold shower and some robusto-bean coffee.

:rolleyes:

Well I’m not a medium. If it’s too hard to give the information I would have liked, I cannot imagine what the problem could be and then I cannot try to help you anymore. :mad:

I don’t understand what you mean by “The code you gave cannot help us because there’s nothing about your lights. How do you create them ? Where do you call the light functions ? This is so important when doing lighting.”.

There are no light functions? The lights are created in this function:

GLfloat Light_Ambient1[] = {0.5f, 0.5f, 0.5f, 1.0f};  //RGBA of ambient light
GLfloat Light_Diffuse1[] = {0.0f, 0.0f, 0.0f, 1.0f};  //RGBA of light scattered after impact
GLfloat Light_Position1[]= {0.0f, 25.0f, 0.0f, 1.0f}; //Position of light source
GLfloat Light_Specular1[]= {0.0f, 0.0f, 0.0f, 1.0f};  //RGBA of bounced beam

GLfloat Light_Ambient2[] = {0.5f, 0.5f, 0.5f, 1.0f};  //RGBA of ambient light
GLfloat Light_Diffuse2[] = {0.0f, 0.0f, 0.0f, 1.0f};  //RGBA of light scattered after impact
GLfloat Light_Position2[]= {25.0f, 25.0f, 37.0f, 1.0f}; //Position of light source
GLfloat Light_Specular2[]= {0.0f, 0.0f, 0.0f, 1.0f};  //RGBA of bounced beam

void Init(HWND hwnd)
{
	ghwnd = hwnd;
	GetClientRect(ghwnd, &gRect);	//get rect into our handy global rect
	InitializeOpenGL(gRect.right, gRect.bottom);// initialise openGL
 
	//OpenGL settings
	glShadeModel(GL_SMOOTH);							// Enable Smooth Shading
	glClearColor(0.0f, 0.0f, 0.0f, 0.5f);				// Black Background
	glClearDepth(1.0f);									// Depth Buffer Setup
	glEnable(GL_DEPTH_TEST);							// Enables Depth Testing
	glDepthFunc(GL_LEQUAL);								// The Type Of Depth Testing To Do
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);	// Really Nice Perspective Calculations
	glEnable(GL_LIGHTING);								//Enables Lighting
	glEnable(GL_TEXTURE_2D);						// Enable Texture Mapping

//glClearAccum(0.0f,0.0f,0.0f,0.5f); 
//glClear(GL_ACCUM_BUFFER_BIT); 

	glLightfv(GL_LIGHT1, GL_AMBIENT,  Light_Ambient1);
	glLightfv(GL_LIGHT1, GL_DIFFUSE,  Light_Diffuse1);
	glLightfv(GL_LIGHT1, GL_POSITION, Light_Position1);
	glLightfv(GL_LIGHT1, GL_SPECULAR, Light_Specular1);
	glEnable(GL_LIGHT1);							// Enable Light One

	glLightfv(GL_LIGHT2, GL_AMBIENT,  Light_Ambient2);
	glLightfv(GL_LIGHT2, GL_DIFFUSE,  Light_Diffuse2);
	glLightfv(GL_LIGHT2, GL_POSITION, Light_Position2);
	glLightfv(GL_LIGHT2, GL_SPECULAR, Light_Specular2);
	glEnable(GL_LIGHT2);							// Enable Light One

	//Load External Data
	InitialiseModelList();							
	LoadModels();
	LoadTextures();
	LoadRawFile("Data/Terrain.raw", MAP_SIZE * MAP_SIZE, g_HeightMap);	// Load the terrain

}

but i’ve allready posted this…so i’m not sure if there’s something else you need, because that is all the light-orientated code in the program.

You set lights to only generate ambient color (black diffuse, black specular) and then you set material to only accept diffuse lighting (black ambient, black specular).

GLfloat Light_Ambient1[] = {0.5f, 0.5f, 0.5f, 1.0f};  //RGBA of ambient light
GLfloat Light_Diffuse1[] = {0.5f, 0.5f, 0.5f, 1.0f};  //RGBA of light scattered after impact
GLfloat Light_Position1[]= {0.0f, 25.0f, 0.0f, 0.0f}; //Position of light source
GLfloat Light_Specular1[]= {0.5f, 0.5f, 0.5f, 1.0f};  //RGBA of bounced beam

       glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
        glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
        glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
        glMaterialf(GL_FRONT, GL_SHININESS, low_shininess);
        glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);

I changed the material and the light values but i’m really not sure what im aiming for. if you could give me an idea as to what sorta numbers i need that’d be great. though all the light looks balanced and the ground is still red :stuck_out_tongue:

http://www.sgi.com/products/software/opengl/examples/redbook/

now, if you really want to understand the code in those demos, you should read the redbook, if it’s not too much trouble.

http://www.rush3d.com/reference/opengl-redbook-1.1/chapter06.html

   GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
   GLfloat mat_shininess[] = { 50.0 };
   GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
   GLfloat light_ambient[] = {1.0f, 1.0f, 1.0f, 1.0f};

Kept it simple, and yet everything is still really red (like…no change). Could it be something to do with the colour of the texture sticking around?

use glEnable(GL_COLOR_MATERIAL); now a simple glColor3f(1.0f,1.0f,1.0f) and you should be done.
See also glColorMaterial.