一、实验实习目的及要求
目的:
1、理解光照模型,特别是phong简单光照模型原理,会用OpenGL绘制具有明暗效果的简单三维图形;
2、了解简单的交互式技术,用户可以简单控制图形。
要求:
- 使用OpenGL绘制一个简单的三维图形,例如立方体,球;
2.为该图形添加光照,使其具有明暗效果;
3.添加鼠标消息函数,用户可以通过鼠标浏览该三维图形;
二、实验实习设备(环境)及要求(软硬件条件)
1.高性能微机;
2.有基本的图形I/O设备;
3.有相应的配套软件,可视化程序设计环境;
三、实验实习内容与步骤
实验内容:
用OpenGL绘制一个简单的三维图形球,并且使用phong光照模型模拟物体表面对光的反射作用。
实验步骤:
1.算法、原理清晰,有详细的设计步骤;
2.依据算法、步骤或程序流程图,用C++语言编写源程序;
3.编辑源程序并进行调试;
4.进行运行测试,并结合情况进行调整;
5.对运行结果进行保存与分析;
6.打印源程序或把源程序以文件的形式提交;
7.按格式书写实验报告。
四、实验实习过程或算法(源程序、代码)
#include "windows.h"
#include <gl/glut.h>
#define SCREEN_WIDTH 480
#define SCREEN_HEIGHT 480
static int spin = 0; // 光源旋转角度
void init(void)
{
// 定义镜面材料颜色
GLfloat mat_specular[] = {0.0, 1.0, 1.0, 1.0};
// 定义材料光泽度
GLfloat mat_shininess[] = {50.0};
// 光源位置、环境光、漫反射光
GLfloat light_position[] = {7.0, 7.0, 1.0, 0.0};
GLfloat light_ambient[] = {5.0, 0.0, 5.0, 0.0};
GLfloat white_light[] = {1.0, 1.0, 1.0, 1.0};
GLfloat lmodel_ambient[] = {0.5, 0.5, 0.5, 5.0};
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_SMOOTH);
// 设置物体前面接受光照
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
// 设置光源属性
glLightfv(GL_LIGHT0, GL_POSITION, light_position);//光源位置齐次坐标(x,y,z,w)
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);//RGBA模式下环境光
glLightfv(GL_LIGHT0, GL_DIFFUSE, white_light);//RGBA模式下漫反射光
glLightfv(GL_LIGHT0, GL_SPECULAR, white_light);//RGBA模式下镜面光
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
glEnable(GL_LIGHTING);//启用光照
glEnable(GL_LIGHT0);//打开第一个灯光
glEnable(GL_DEPTH_TEST);//剔除隐藏面,使能深度检测
}
void display(void)
{
GLfloat light_position[] = {1.0, 1.0, 1.0, 0.0};
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glPushMatrix();
glRotatef(spin, 1.0, 0.0, 0.0);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glTranslatef(0.0, 0.0, 1.5);
glDisable(GL_LIGHTING);
glEnable(GL_LIGHTING);
glPopMatrix();
// 绘制立方体的六个面
glBegin(GL_QUADS);
// Front face
glColor3f(1.0, 0.0, 0.0); // 红色
glVertex3f(-0.5, -0.5, 0.5);
glVertex3f(0.5, -0.5, 0.5);
glVertex3f(0.5, 0.5, 0.5);
glVertex3f(-0.5, 0.5, 0.5);
// Back face
glColor3f(0.0, 1.0, 0.0); // 绿色
glVertex3f(-0.5, -0.5, -0.5);
glVertex3f(0.5, -0.5, -0.5);
glVertex3f(0.5, 0.5, -0.5);
glVertex3f(-0.5, 0.5, -0.5);
// Left face
glColor3f(0.0, 0.0, 1.0); // 蓝色
glVertex3f(-0.5, -0.5, 0.5);
glVertex3f(-0.5, 0.5, 0.5);
glVertex3f(-0.5, 0.5, -0.5);
glVertex3f(-0.5, -0.5, -0.5);
// Right face
glColor3f(1.0, 1.0, 0.0); // 黄色
glVertex3f(0.5, -0.5, 0.5);
glVertex3f(0.5, 0.5, 0.5);
glVertex3f(0.5, 0.5, -0.5);
glVertex3f(0.5, -0.5, -0.5);
// Top face
glColor3f(1.0, 0.0, 1.0); // 紫色
glVertex3f(-0.5, 0.5, 0.5);
glVertex3f(0.5, 0.5, 0.5);
glVertex3f(0.5, 0.5, -0.5);
glVertex3f(-0.5, 0.5, -0.5);
// Bottom face
glColor3f(0.0, 1.0, 1.0); // 青色
glVertex3f(-0.5, -0.5, 0.5);
glVertex3f(0.5, -0.5, 0.5);
glVertex3f(0.5, -0.5, -0.5);
glVertex3f(-0.5, -0.5, -0.5);
glEnd();
glPopMatrix();
glFlush();
}
//鼠标简单控制物体旋转
void mouse(int button, int state, int x, int y)
{
switch (button)
{
case GLUT_LEFT_BUTTON:
if (state == GLUT_DOWN)
{
spin = (spin + 10) % 360;
glutPostRedisplay();
}
break;
case GLUT_RIGHT_BUTTON:
if (state == GLUT_DOWN)
{
spin = (spin - 10) % 360;
glutPostRedisplay();
}
break;
default:
break;
}
}
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
// 透视投影
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w < h)
{
glOrtho(-1.5, 1.5, -1.5 * (GLfloat) h / (GLfloat) w,
1.5 * (GLfloat)h / (GLfloat)w, -10.0, 10.0);
}
else
{
glOrtho(-1.5 * (GLfloat) h / (GLfloat) w,
1.5 * (GLfloat) h / (GLfloat) w,
-1.5, 1.5, -10.0, 10.0);
}
// 当前为模型视图矩阵
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);//初始化OpenGL
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE|GLUT_DEPTH);
glutInitWindowSize(SCREEN_WIDTH, SCREEN_HEIGHT);
glutInitWindowPosition(50, 100);
glutCreateWindow("立方体");
init();
glutDisplayFunc(&display);
glutReshapeFunc(&reshape);
glutMouseFunc(&mouse);
glutMainLoop();
return 0;
}