To use lighting in OpenGL, we must keep several things in mind.
We have to first enable lighting by using glEnable(GL_LIGHTING)
OpenGL supports maximum of 8 light sources named from GL_LIGHT0 to GL_LIGHT7.
By default, when a lighting in enabled in OpenGL, only one light source is enabled, and it is situated along +ve Z-axis and emits WHILTE AMBIENT light.
We have to enable the light sources by using glEnable() function.
For example, the following code enables GL_LIGHT0:
glEnable(GL_LIGHT0);
![]() |
Output of Enabling Single Light Source |
Once lighting is enabled, color of the object is immediately replaced by color of the light sources.
In OpenGL, we can position the light sources along the principal axes as well as specify the types of light sources.
Types of Light Sources in OpenGL:
Light Sources in OpenGL can be categorized into three types:
- Ambient Light Source: This light source has same intensity throughout the scene. Hence mathematically, intensity of ambient light is a constant value, and hence objects look dull in the scene due to ambient light source.
![]() |
Effect of Ambient Light on Object |
To specify an ambient light source in OpenGL, we need to first specify the color of ambient intensity and then need to apply it to light source.
For example:
float ambient_light0[] = {1.0, 1.0, 1.0, 0.0};
glLightfv(GL_LIGHT0, GL_AMBIENT, ambient_light0);
First three elements of ambient_light0 array specify a low intensity WHITE light (we can specify values between 0 to 255, 0 being least intense and 255 being highest intense).
Fourth element signifies BLENDING value and is used where-in multiple light interactions are involved. But to see the effect, we need to enable BLENDING option.
glLightfv() function is used to specify the types of light sources. The above code specifies ambient light source for GL_LIGHT0.
- Diffuse Light Source: Diffuse light source is treated as a point light source that emits light equally in all directions. The intensity of a point light source is inversely proportional to square of the distance between the source and the surface. Objects tend to have high contrast due to diffuse lights. Also objects tend to look either darker or brighter. Hence to compensate high contrasting effect, we usually add ambient light also to a scene.
Specification of Diffuse Light Source in OpenGL:
float diffuse_light0[] = {50.0, 0.0, 0.0, 0.0};
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse_light0);
![]() |
Effect of Diffuse Light on Object |
- Specular Light Source: Specular light source is a spotlight and is characterized by a narrow range of angles through which light is emitted. Specular lights specify how the object shines when light is incident on the object. But to get dramatic effects, we must also specify material properties for the object of interest.
Specification of Specular Light Source in OpenGL:
float specular_light0[] = {50.0, 0.0, 0.0, 0.0};
glLightfv(GL_LIGHT0, GL_SPECULAR, specular_light0);
![]() |
Effect of Specular Light on Object |
Positioning Light Sources in OpenGL:
Light Sources in OpenGL can be positioned along X, Y and Z-axis respectively.
Position of the light source is specified with a four element array.
First three elements specify the position of the light source.
(1, 0, 0) positions light source along X-axis.
(0, 1, 0) positions light source along Y-axis.
(0, 0, 1) positions light source along Z-axis.
Fourth element specifies whether a light source is at INFINITE distant from the object or not. Value of 0 signifies an INFINITE distant light source and value of 1 signifies a FINITE distant light source.
The following code positions RED DIFFUSE infinite distant light source along X-axis, BLUE AMBIENT finite distant light source along Y-axis and GREEN SPECULAR infinite distant light source along Z-axis:
float light0_position[] = {1, 0, 0, 0};
float light0_diffuse[] = {50, 0, 0, 0};
float light1_position[] = {0, 6, 0, 1};
float light1_ambient[] = {0, 0, 50, 0};
float light2_position[] = {0, 0, 1, 0};
float light2_specular[] = {0, 50, 0, 0};
glLightfv(GL_LIGHT0, GL_POSITION, light0_position);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);
glLightfv(GL_LIGHT1, GL_POSITION, light1_position);
glLightfv(GL_LIGHT1, GL_AMBIENT, light1_ambient);
glLightfv(GL_LIGHT2, GL_POSITION, light2_position);
glLightfv(GL_LIGHT2, GL_SPECULAR, light2_specular);
![]() |
Effect of Three Light Sources |
Material Specifications in OpenGL:
The following code specifies Ambient Reflection value of 0.25 to the material:
float material_ambient[] = {0.25, 0.25, 0.25, 1.0};
glMaterialfv(GL_FRONT, GL_AMBIENT, material_ambient);
The function glMaterialfv() takes three arguments. Meaning of each of the arguments is explained below:
First argument specifies the face or faces that are being updated. It must have one of the following values:
- GL_FRONT
- GL_BACK
- GL_FRONT_AND_GL_BACK
Second argument specifies the material parameter of the face or faces being updated. The parameters that can be specified using glMaterialfv, and their interpretations by the lighting equation, are as follows:
- GL_AMBIENT: The fourth parameter must contain four floating-point values that specify the ambient RGBA reflectance of the material. Integer values are mapped linearly such that the most positive represent-able value maps to 1.0, and the most negative represent-able value maps to -1.0. Floating-point values are mapped directly. Neither integer nor floating-point values are clamped. The default ambient reflectance for both front-facing and back-facing materials is (0.2, 0.2, 0.2, 1.0).
- GL_DIFFUSE: The fourth parameter must contain four floating-point values that specify the diffuse RGBA reflectance of the material. Integer values are mapped linearly such that the most positive represent-able value maps to 1.0, and the most negative represent-able value maps to -1.0. Floating-point values are mapped directly. Neither integer nor floating-point values are clamped. The default diffuse reflectance for both front-facing and back-facing materials is (0.8, 0.8, 0.8, 1.0).
- GL_SPECULAR: The fourth parameter must contain four floating-point values that specify the specular RGBA reflectance of the material. Integer values are mapped linearly such that the most positive represent-able value maps to 1.0, and the most negative represent-able value maps to -1.0. Floating-point values are mapped directly. Neither integer nor floating-point values are clamped. The default specular reflectance for both front-facing and back-facing materials is (0.0, 0.0, 0.0, 1.0).
- GL_EMISSION: The fourth parameter must contain four floating-point values that specify the RGBA emitted light intensity of the material. Integer values are mapped linearly such that the most positive represent-able value maps to 1.0, and the most negative represent-able value maps to -1.0. Floating-point values are mapped directly. Neither integer nor floating-point values are clamped. The default emission intensity for both front-facing and back-facing materials is (0.0, 0.0, 0.0, 1.0).
- GL_SHININESS: The fourth parameter is a single integer value that specifies the RGBA specular exponent of the material. Integer values are mapped directly. Only values in the range [0, 127] are accepted. The default specular exponent for both front-facing and back-facing materials is 0.
- GL_AMBIENT_AND_DIFFUSE: Equivalent to calling glMaterial twice with the same parameter values, once with GL_AMBIENT and once with GL_DIFFUSE.
- GL_COLOR_INDEXES: The fourth parameter must contain three floating-point values that specify the color indexes for ambient, diffuse, and specular lighting. These three values, and GL_SHININESS, are the only material values used by the color-index mode lighting equation.
OpenGL Code that demonstrates specification of light sources, positioning of light sources along principal axes and also specifies material properties to the object TEAPOT:
1: #include<stdio.h>
2: #include<math.h>
3: #include<GL/glut.h>
4: void myInit()
5: {
6: glClearColor(0.0, 0.0, 0.0, 0.0);
7: glColor3f(1.0, 0.0, 0.0);
8: glMatrixMode(GL_PROJECTION);
9: glLoadIdentity();
10: glOrtho(-2.0, 2.0, -2.0, 2.0, -2.0, 2.0); // set viewing volume to 2 X 2 X 2
11: glMatrixMode(GL_MODELVIEW);
12: glEnable(GL_LIGHT0);
13: glEnable(GL_LIGHT1);
14: glEnable(GL_LIGHT2);
15: float light0_position[] = {1, 0, 0, 0};
16: float light0_diffuse[] = {50, 0, 0, 0};
17: float light1_position[] = {0, 1, 0, 0};
18: float light1_ambient[] = {0, 0, 50, 0};
19: float light2_position[] = {0, 0, 1, 0};
20: float light2_specular[] = {0, 50, 0, 0};
21: glLightfv(GL_LIGHT0, GL_POSITION, light0_position);
22: glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);
23: glLightfv(GL_LIGHT1, GL_POSITION, light1_position);
24: glLightfv(GL_LIGHT1, GL_AMBIENT, light1_ambient);
25: glLightfv(GL_LIGHT2, GL_POSITION, light2_position);
26: glLightfv(GL_LIGHT2, GL_SPECULAR, light2_specular);
27: float material_ambient[] = {0.25, 0.25, 0.25, 1.0};
28: float material_diffuse[] = {0.8, 0.8, 0.8, 1.0};
29: float material_specular[] = {0.8, 0.8, 0.8, 1.0};
30: float shininess = 50;
31: glMaterialfv(GL_FRONT, GL_AMBIENT, material_ambient);
32: glMaterialfv(GL_FRONT, GL_DIFFUSE, material_diffuse);
33: glMaterialfv(GL_FRONT, GL_SPECULAR, material_specular);
34: glMaterialf(GL_FRONT, GL_SHININESS, shininess);
35: }
36: void display()
37: {
38: glRotatef(-0.1, 1.0, 1.0, 1.0);
39: glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
40: glutSolidTeapot(1.0);
41: glFlush();
42: }
43: int main(int argc, char **argv)
44: {
45: glutInit(&argc, argv);
46: glutInitDisplayMode(GLUT_SINGLE | GLUT_DEPTH | GLUT_RGB );
47: glutInitWindowSize(500, 500);
48: glutInitWindowPosition(0, 0);
49: glutCreateWindow("Lighting in OpenGL");
50: glutDisplayFunc(display);
51: glutIdleFunc(display);
52: glEnable(GL_DEPTH_TEST);
53: glEnable(GL_LIGHTING);
54: myInit();
55: glutMainLoop();
56: return 0;
57: }
![]() |
Output |
No comments:
Post a Comment