cpp
复制代码
#include<gl/glut.h>
#include <math.h>
/**************************************/
/* 设置灯旋转角度初始值和一些所用参数 */
/**************************************/
static GLfloat yrot = -100.0;
static GLfloat zrot = 40.0;
const GLfloat PI = 3.1415926f;
const GLfloat R = 10.0f;
void init()
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_SMOOTH);
/********************************************/
/* 设置灯泡光源属性:环境光、镜面光、散色光 */
/********************************************/
GLfloat light_ambient[] = { 0.2, 0.2, 0.2, 1.0 };
GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
/***************************************************************/
/* 设置灯泡光源(移动光源)属性:光锥切角、初始位置、聚光灯光线方向 */
/***************************************************************/
GLfloat light_position[] = { 13.0, -3.0, 0.0 };
GLfloat spot_direction[] = { 0.0, -1.0, 0.0 };
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 40.0);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, spot_direction);
/********************************************************/
/* 设置固定光源(LIGHT1)属性:位置、环境光、镜面光、散色光 */
/********************************************************/
GLfloat light_position1[] = { 0.0, 20.0, 0.0, 1.0 };
GLfloat light_ambient1[] = { 0.2, 0.2, 0.2, 1.0 };
GLfloat light_specular1[] = { 0.1, 0.1, 0.1, 1.0 };
GLfloat light_diffuse1[] = { 0.1, 0.1, 0.1, 1.0 };
glLightfv(GL_LIGHT1, GL_POSITION, light_position1);
glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient1);
glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular1);
glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse1);
/************************************************/
/* 设置材料属性:环境光、镜面光、散色光、镜面指数 */
/************************************************/
GLfloat mat_ambient[] = { 0.2, 0.2, 0.2, 1.0 };
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat mat_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat mat_shininess[] = { 120.0 };
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
/************************************/
/* 调用glColorMaterial设置材料属性 */
/* 设置材料属性为颜色追踪。 */
/* 启用颜色追踪 */
/************************************/
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
glEnable(GL_COLOR_MATERIAL);
/********************************/
/* 开启光源、移动光源、固定光源 */
/* 开启深度测试、法向量单位化 */
/********************************/
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
glEnable(GL_DEPTH_TEST);
glEnable(GL_NORMALIZE);
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
GLUquadricObj* objCylinder = gluNewQuadric();
//画台灯底座
glPushMatrix();
glColor3f(0.12549, 0.69804, 0.66667);
//底座使用一个立方体
/*glTranslated(0.0, -20.0, 10.0);
glScalef(12.0, 1.0, 12);
glutSolidCube(2.0);*/
/*********************************************************/
/* 为了使法向量更多,从而使光照效果更佳, */
/* 下面使用7*7的小立方体,拼成一个大的立方体作为台灯底座 */
/*********************************************************/
glTranslated(0.0, -20.0, 0.0);
/*for(int m=5; m>-2; m--){
for(int n=-3; n<4; n++){
glPushMatrix();
glTranslated(3*n, 0.0, 3*m);
glScalef(1.0, 0.5, 1.0);
glutSolidCube(3);
glPopMatrix();
}
}*/
/* 使用200*200小立方体画台灯底座 */
for (int m = 180; m > -20; m--) {
for (int n = -100; n < 100; n++) {
glPushMatrix();
glTranslated(0.1 * n, 0.0, 0.1 * m);
glScalef(1.0, 10.0, 1.0);
glutSolidCube(0.1);
glPopMatrix();
}
}
glPopMatrix();
/*************************************************/
/* 画灯杆 */
/* 使用gluCylinder画圆柱,圆柱初试状态沿着-Z轴方向 */
/**************************************************/
//灯杆第一段
glPushMatrix();
glColor3f(0.7333, 1.0, 1.0);
glRotatef(90.0, 1.0, 0.0, 0.0);
gluCylinder(objCylinder, 1.0, 1.0, 21.0, 100, 100);// baseRadius,topRadius, height, slices, stacks
glPopMatrix();
//灯杆第二段
glPushMatrix();
glRotatef(yrot, 0.0f, 1.0f, 0.0f);
glRotatef(zrot, 0.0f, 0.0f, 1.0f);
glColor3f(0.7333, 1.0, 1.0);
glTranslatef(4.0, 6.93, 0.0);
glRotatef(90.0, 1.0, 0.0, 0.0);
glRotatef(-30.0, 0.0, 1.0, 0.0);
gluCylinder(objCylinder, 1.0, 1.0, 8.0, 100, 100);// baseRadius,topRadius, height, slices, stacks
glPopMatrix();
//灯杆第三段
glPushMatrix();
glRotatef(yrot, 0.0f, 1.0f, 0.0f);
glRotatef(zrot, 0.0f, 0.0f, 1.0f);
glColor3f(0.7333, 1.0, 1.0);
glTranslatef(4.0, 6.93, 0.0);
glRotatef(90.0, 1.0, 0.0, 0.0);
glRotatef(90.0, 0.0, 1.0, 0.0);
gluCylinder(objCylinder, 1.0, 1.0, 10.0, 100, 100);// baseRadius,topRadius, height, slices, stacks
glPopMatrix();
//灯杆第四段
glPushMatrix();
glRotatef(yrot, 0.0f, 1.0f, 0.0f);
glRotatef(zrot, 0.0f, 0.0f, 1.0f);
glColor3f(0.7333, 1.0, 1.0);
glTranslatef(13, 7.23, 0.0);//6.93
glRotatef(90.0, 1.0, 0.0, 0.0);
gluCylinder(objCylinder, 1.0, 1.0, 5.3, 100, 100);// baseRadius,topRadius, height, slices, stacks
glPopMatrix();
//灯壳
//画圆锥的面
glPushMatrix();
glRotatef(yrot, 0.0f, 1.0f, 0.0f);
glRotatef(zrot, 0.0f, 0.0f, 1.0f);
glColor3f(0.12549, 0.69804, 0.66667);
glBegin(GL_TRIANGLE_FAN);
glVertex3f(13.0f, 2.5f, 0.0f);
for (GLfloat angle = 0; angle <= 2.0 * PI; angle += PI / 10.0f) {
GLfloat x = 13 + R * sin(angle);
GLfloat z = R * cos(angle);
glVertex3f(x, -3.27, z);
}
glVertex3f(13.0f, -3.27, 10.0f);
glEnd();
glPopMatrix();
//灯泡
glPushMatrix();
glRotatef(yrot, 0.0f, 1.0f, 0.0f);
glRotatef(zrot, 0.0f, 0.0f, 1.0f);
/***************************************************************/
/* 设置灯泡光源(移动光源)属性:光锥切角、初始位置、聚光灯光线方向 */
/***************************************************************/
GLfloat light_position[] = { 13.0, -3.0, 0.0 };
GLfloat spot_direction[] = { 0.0, -1.0, 0.0 };
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 40.0);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, spot_direction);
glDisable(GL_LIGHTING);
glColor3f(1.0, 0.6, 0.2);
glTranslatef(13.0, -3.4, 0.0);
glutSolidSphere(3.0, 100, 100);
glEnable(GL_LIGHTING);
glPopMatrix();
glutSwapBuffers();
}
void changesize(int w, int h)
{
GLfloat nRange = 40.0;
if (h == 0)
h = 1;
glViewport(0.0, 0.0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho(-nRange, nRange, -nRange * h / w, nRange * h / w, -nRange, nRange);
else
glOrtho(-nRange * w / h, nRange * w / h, -nRange, nRange, -nRange, nRange);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(5.0, 5.0, 10.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
}
void SpecialKeys(int key, int x, int y)
{
if (key == GLUT_KEY_UP && zrot < 50.0)
zrot += 5.0;
if (key == GLUT_KEY_DOWN && zrot > -30.0)
zrot -= 5.0;
if (key == GLUT_KEY_LEFT)
yrot -= 5.0f;
if (key == GLUT_KEY_RIGHT)
yrot += 5.0f;
glutPostRedisplay();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(800, 600);
glutInitWindowPosition(200, 20);
glutCreateWindow("台灯");
init();
glutDisplayFunc(display);
glutReshapeFunc(changesize);
glutSpecialFunc(SpecialKeys);
glutMainLoop();
return 0;
}