定向光
这一节我们使用定向光,涉及漫射光的高级应用和镜面光源。
我们将展示镜面光的显示效果,使用红色的小球和照在小球上的光源。
程序代码:
第一步依然是定义属性值,这里我们要加上镜面光的属性值定义。
float lightAmbient[] = { 0.2f, 0.0f, 0.0f, 1.0f };
float lightDiffuse[] = { 0.5f, 0.0f, 0.0f, 1.0f };
float lightSpecular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
同样,定义材质对镜面光的反射值
float matAmbient[] = { 1.0f, 1.0f, 1.0f, 1.0f };
float matDiffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
float matSpecular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
因为是定向光,所以我们需要知道光的位置和方向,下面代码就是定义位置和方向,
float lightPosition[] = { 2.0f, 2.0f, 3.0f, 0.0f };
float lightDirection[] = { -2.0f, -2.0f, -3.0f };
下面启用第一个光源
void init()
{
? ? glEnable(GL_LIGHTING);
? ? glEnable(GL_LIGHT0);
设置材质属性
? ? glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, matAmbient);
? ? glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, matDiffuse);
? ? glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, matSpecular);
另一个可以用glMaterialf 设置的属性是GL_SHININESS,它的值在0到128之间,它表明镜面光的焦距度,值越大镜面光焦距越多。
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 20.0f);
下一步设置光属性
? ? glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmbient);
? ? glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuse);
? ? glLightfv(GL_LIGHT0, GL_SPECULAR, lightSpecular);
设置光源的位置和方向,使用glLightfv 函数,它的第二个参数可以指明设置的是位置还是方向。
? ? glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
? ? glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, lightDirection);
另一个有用的标记是GL_SPOT_CUTOFF,它指定光锥体的大小,想象一个火把远离你时所产生的火光锥体,1.2将产生2.4度大的光锥体,如果设置为180度,则发射的光会照到各个角落。
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 1.2f);
我们要讨论的下一个标记是GL_SPOT_EXPONENT,它控制圆锥体内光强分布的指数因子,值在0到128之间,值越大,锥体轴线部分的光越强。
glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 20.0f);
glLightf 函数还有三个标记可以设置,是用来控制衰减方式的,分别是:GL_CONSTANT_ATTENUATION(1), GL_LINEAR_ATTENUATION(0),GL_QUADRATIC_ATTENUATION。即常数衰减,线性衰减和二次衰减。括号中的值是它的默认值。
衰减指的是光的强度逐渐减弱,就像你离火光越来越远一样。设置这些属性会导致程序大幅减慢。
display 函数余下部分不变。
? ? glEnable(GL_DEPTH_TEST);
? ? glDepthFunc(GL_LEQUAL);
? ? glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
? ? glClearDepthf(1.0f);
? ? glEnable(GL_CULL_FACE);
? ? glShadeModel(GL_SMOOTH);
}
我们简单的使用glutSolidSphere / ugSolidSpheref 来创建求面体,这个球面体由水平24栈和垂直24片组成,这样可以更多的体现光照细节。
也许你奇怪我们为什么没有指定球面的法线,令人高兴的是UG / GLUT|ES库中创建的形状物体,法线是自动生成的,均由库自动计算,这大大简化了我们的任务。
void display()
{
? ?glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
? ?glLoadIdentity();
? ?gluLookAtf(
? ?? ???0.0f, 0.0f, 4.0f,
? ?? ???0.0f, 0.0f, 0.0f,
? ?? ???0.0f, 1.0f, 0.0f);
? ?glRotatef(xrot, 1.0f, 0.0f, 0.0f);
? ?glRotatef(yrot, 0.0f, 1.0f, 0.0f);
? ?ugSolidSpheref(1.0f, 24, 24);
? ?glFlush();
? ?glutSwapBuffers();
}
运行程序,会呈现一个红色的球,注意镜面光源在球的右上方,那么现在你可以把定向光加入自己的程序了。